【问题标题】:@Autowired and UnsatisfiedDependencyException in a junit testjunit 测试中的 @Autowired 和 UnsatisfiedDependencyException
【发布时间】:2017-09-20 17:13:12
【问题描述】:

我正在编写一个 junit 测试,它必须从一些必须与 Cassandra 交互的自动装配依赖项中调用一些方法,但我得到了这个异常:

[ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.21 s <<< FAILURE! - in unicon.mattheews.admin.service.repository.test.AdminUserRepositoryTests
[ERROR] testFindByUsername(unicon.mattheews.admin.service.repository.test.AdminUserRepositoryTests)  Time elapsed: 0.001 s  <<< ERROR!
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'unicon.mattheews.admin.service.repository.test.AdminUserRepositoryTests': Unsatisfied dependency expressed through field 'repository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'unicon.matthews.admin.service.repository.AdminUserRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
 Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'unicon.matthews.admin.service.repository.AdminUserRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

这是junit测试:

import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.util.Version;
import org.springframework.test.context.junit4.SpringRunner;

import example.springdata.cassandra.util.CassandraKeyspace;
import unicon.matthews.admin.AdminUser;
import unicon.matthews.admin.service.repository.AdminUserRepository;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = CassandraConfiguration.class)
public class AdminUserRepositoryTests {

@ClassRule public final static CassandraKeyspace CASSANDRA_KEYSPACE = CassandraKeyspace.onLocalhost().atLeast(Version.parse("3.0"));

@Autowired AdminUserRepository repository;

@Before
public void setUp() throws Exception {
    repository.deleteAll();
}

@Test
public void testFindByUsername() {

    try {
        final String userName = "aironman";
        AdminUser.Builder myBuilderAdmin = AdminUser.Builder.class.newInstance();
        myBuilderAdmin.withId("id");
        myBuilderAdmin.withEmailAddress("some@domain.com");
        myBuilderAdmin.withOrgId("orgId");
        myBuilderAdmin.withPassword("some-password");
        myBuilderAdmin.withSuperAdmin(Boolean.TRUE);
        myBuilderAdmin.withTenantId("tenantId");
        myBuilderAdmin.withUserName(userName);
        //que viene aqui exactamente?
        Map<String, String> someMetadata = new HashMap<String, String>();
        someMetadata.put("some-key","some-value");
        myBuilderAdmin.withMetadata(someMetadata);
        AdminUser myAdminUser = myBuilderAdmin.build();
        repository.save(myAdminUser);
        Optional<AdminUser> loadedUserName = repository.findByUsername(userName);
        assertNotNull(loadedUserName);
        // assertThat(repository.findOne(homer.id).isPresent(), is(true));
        assertEquals("something went wrong!",userName,loadedUserName.get().getUsername());
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }

    System.out.println("Done testFindByUsername!");
}

}

AdminUserRepository 看起来像:

import java.util.Optional;
import org.springframework.data.cassandra.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import unicon.matthews.admin.AdminUser;


@Repository
public interface AdminUserRepository extends CrudRepository<AdminUser, String> {

@Query("select * from AdminUser where username = ?0")
Optional<AdminUser> findByUsername(final String userName);

}

CassandraConfiguration 看起来像:

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.cassandra.config.SchemaAction;
import org.springframework.data.cassandra.config.java.AbstractCassandraConfiguration;
import org.springframework.data.cassandra.repository.config.EnableCassandraRepositories;

@Configuration
@EnableAutoConfiguration
class CassandraConfiguration {

@Configuration
@EnableCassandraRepositories
static class CassandraConfig extends AbstractCassandraConfiguration {

    @Override
    public String getKeyspaceName() {
        return "example";
    }

    @Override
    public SchemaAction getSchemaAction() {
        return SchemaAction.RECREATE;
    }
}

}

我了解 spring 正在尝试实例化这个 AdminUserRepository 类,该类是使用 spring-data 项目中的 CrudRepository 创建的。假设如果我用@Repository 标记这个接口,spring 将在spring 上下文中实例化该类,以便另一个bean 能够在其中自动装配它,那么,为什么spring 不能实例化依赖关系?

AdminUserRepository 接口位于 src/main/java 中,AdminUserRepositoryTests 位于 src/test/java 中。

这是我的真实pom.xml,请帮忙。

【问题讨论】:

  • CassandraConfiguration 和 AdminUserRepository 类位于哪些包中?配置应该是所有其他类的“根”。
  • CassandraConfiguration 位于与 AdminUserRepositoryTests 相同的包中,即 src/test/java/some-package。依赖 AdminUserRepository 位于 src/main/java/another-package 中。如果我想测试这个 AdminUserRepository,¿我必须将它复制到 src/test/java/some-package 中吗?
  • 这可能是个问题。你不介意将 CassandraConfiguration 放到 src/main/java/some.package 中吗?而且,正如我之前所说,AdminUserRepository 应该放在 src/main/java/some.package.another.one/
  • 就是这样!现在我得到另一个异常: org.springframework.cassandra.support.exception.CassandraInvalidQueryException: unconfigured table adminuser;嵌套异常是 com.datastax.driver.core.exceptions.InvalidQueryException: unconfigured table adminuser 但这是另一个问题...我想我必须首先在所选键空间中创建表 adminuser。

标签: spring-boot spring-data-cassandra


【解决方案1】:

使用@Repository 标记Spring 数据存储库实际上并没有做任何事情。如果您不想启用 CrudRepository,则需要使用 @EnableJpaRepositories 注释您的配置。但是,由于您使用的是 Cassandra,我认为您更有可能想要使用 CassandraRepository ?

public interface AdminUserRepository extends CassandraRepository<AdminUser, String> {

@Query("select * from AdminUser where username = ?0")
Optional<AdminUser> findByUsername(final String userName);

}

【讨论】:

  • 是的,使用 CassandraRepository 接口而不是 CrudRepository 更符合逻辑。你是说我必须用 @EnableJpaRepositories 标记我的 CassandraConfiguration?
  • 不,那只是为了设置一个 CrudRepository bean。 @EnableCassandraRepositories 是为 CassandraRepository afaik 做的,尽管我自己以前没有使用过 Cassandra。
  • 如果你看 CassandraConfiguration 类,有一个 CassandraConfig 扩展了 AbstractCassandraConfiguration 标记为 Configuration 和 EnableCassandraRepositories。 @Plog
  • 老实说,我会提出一个新问题。现在至少解决了 Spring 自动装配问题。
  • @Query 不需要使用 Spring Data Cassandra 1.5。对于 1.4 及更早版本,它是必需的。你也不需要扩展CassandraRepositoryCrudRepository就足够了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-12
  • 1970-01-01
  • 2012-01-19
  • 2017-06-04
  • 2018-07-19
  • 2020-01-08
  • 2018-10-04
相关资源
最近更新 更多