2

我正在开发一个使用 Spring Boot 2 和 Spring Data JDBC 的应用程序。最终的应用程序将使用 MySQL。

我目前有一个持久层和一个服务层以及一些从 CrudRepository 派生的存储库。

对于我的单元测试,我真的想在没有任何数据库的情况下进行单元测试。甚至没有 HSQL。我知道这里有几种不同的哲学可以订阅,但我想切换到纯单元测试,看看它是如何发挥作用的。我将在集成测试中使用数据库。

我的application.properties测试文件夹中有一个单独的文件夹,其中我有一个单独的测试配置。

如果没有定义数据源,Spring Boot 将默认使用 HSQL application.properties。但同样,我想在没有任何数据库的情况下运行我的测试,并且只模拟我的 CrudRepository 实现。我尝试通过在我的以下内容中使用不同的变体来禁用 Spring Boot 的数据库自动配置application.properties

spring.autoconfigure.exclude= \
  org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
  org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration,\
  org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
  org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration

在我的测试中,我试图做这样的事情:

@ExtendWith(SpringExtension.class)
@Transactional
@SpringBootTest
public class UserServiceTest {

    private UserService userService;

    @MockBean
    private UserRepository userRepository;

    @BeforeEach
    void setUp() {
        userService = new UserService(userRepository);
    }

    @Test
    public void doSomeTest() {

         // Test code goes here

    }

}

我在服务中使用基于构造函数的依赖注入。但是,我从 Spring 收到如下错误:

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'package.userRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

我想要的是一个模拟的 userRepository,我可以在其中预先配置一个伪造的存储库以返回虚拟数据。但似乎删除数据库配置会完全删除 CrudRepository,因此 spring boot 应用程序的任何部分都无法启动。还是我错过了其他东西。

我正在使用 Eclipse、Maven、Mockito 和 JUnit5。我应该注意,如果我对测试 mysql 数据库运行“单元测试”,那么一切正常,所以我知道代码或测试或一般设置没有任何问题。问题仅在我想摆脱数据库时才开始。

我是一名初级 Java 开发人员,这样做是为了好玩,所以我可能会遗漏一些明显的东西。在网上搜索 Spring Data JDBC 很困难,因为我几乎只找到与 JPA 相关的解决方案。

4

1 回答 1

1

@SpringBootTest加载所有上下文。春季启动 - @SpringBootTest

在底层,@SpringBootTest 试图模仿 Spring Boot 框架添加的用于创建上下文的过程,例如它根据包结构决定扫描什么,从预定义的位置加载外部配置,可选地运行自动配置启动器等等。

正如我们看到的,这个注解在测试开始之前启动并配置了几乎整个应用程序,我们应该使用@SpringBootTest 编写一个使用应用程序进程和依赖项的集成测试。

包括UserService. 我猜它找不到UserRepository所以它失败了。

我想你应该删除这些字符串

spring.autoconfigure.exclude= \
  org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
  org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration,\
  org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
  org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration

并像这样测试

@ExtendWith(SpringExtension.class)
@SpringBootTest
@Transactional
public class UserServiceTest {

    @TestConfiguration
    class UserServiceTestContextConfiguration {

        @Bean
        public UserService userService() {
            return new UserService(userRepository);
        }
    }

    @Autowired
    private UserService userService;

    @MockBean
    private UserRepository userRepository;

    // write test cases here
}

从这里拿走了

请记住,Spring@TestConfiguration专门处理,所以不要用它“打你的腿” Spring boot – @TestConfiguration

在 Spring Boot 中,任何在使用 @TestConfiguration 注释的顶级类中配置的 bean 都不会通过组件扫描被拾取。我们必须向包含测试用例的类显式注册 @TestConfiguration 类。

于 2020-02-19T11:55:22.310 回答