【Springboot】玩转复杂单元测试启动类-只测试数据访问层(JPA+Mybatis) 和服务层 以及Junit和TestNG

上一篇文章写了一个最复杂的 SpringBootTest启动类,定制化程序奇高,然而有时候仅测试JPA是不够的。
【SpringBoot】复杂单元测试启动类-只测试OpenFeign以及只测试Spring Data JPA

说明
本篇文章更好的解决了类型扫描的问题,避免手写复杂的ComponentScan表达式,以及避免使用 @SpringBootApplication 启动类。

启动类

需求:

  • 测试Spring Data JPA
  • 测试Mybatis
  • 从容器中获得 ObjectMapper
  • 测试单独的 Service
  • 使用TestNG或者使用Junit
  • 阻止Dubbo、Kafka、ElasticSearch 等中间件启动
  • 使用 application-test.properties 配置
  • 使用 Apollo Config 自动配置

基本结构

@SpringBootTest(classes = {JpaConfig.class},
        webEnvironment = SpringBootTest.WebEnvironment.NONE)
@ActiveProfiles("test")
@EnableAutoConfiguration(exclude = {
        DubboAutoConfiguration.class,
        DubboRelaxedBindingAutoConfiguration.class,
        KafkaAutoConfiguration.class,
        ElasticsearchDataAutoConfiguration.class,
        ElasticsearchRepositoriesAutoConfiguration.class,
        ReactiveElasticsearchRepositoriesAutoConfiguration.class,
        ReactiveElasticsearchRestClientAutoConfiguration.class
})
public class DaoTest {
   //...
}

说明

基本测试注解:

  1. @SpringBootTest 声明了 webEnvironment,以及需要扫描的配置类,而不是整个包路径遍历扫描
  2. @ActiveProfiles 声明使用的Profile,对应配置文件 application-test.properties
  3. @EnableAutoConfiguration

其中 JpaConfig.class 是启动 JPA的配置类,该类主要声明 Datasource,以及使用 configurationProperties,从而将Apollo配置中心、配置文件数据源扫描到上下文中。

Mybatis

启动Mybatis的Mapper接口扫描:

  • 其中 @AutoConfigureMybatis 注解 和 @SpringBootTest 兼容。
  • 其中 @AutoConfigureTestDatabase 注解 声明使用真实的数据库,而不是H2。
  • 其中 @MapperScan声明了 dao所在包位置,防止因为启动类包路径不在 dao上层以及dao的包路径存在特殊的位置,而扫描不到Mapper接口的情况。
@MapperScan("com.slankka.company.dao.mapper")
@AutoConfigureMybatis
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)

或者通过如下方式制定,并在 DaoTest 类上 Import

//..
@Import(MappersConfig.class)
//..
public class DaoTest {
 //...
}
@TestConfiguration
@ComponentScan("com.slankka.company.dao.mapstruct")
public class MappersConfig {

}

随意指定需要扫描的 Service

  • 方法一:直接在 @SpringBootTest 上声明 classes
  • 方法二:使用单独的类并@Import

例如

@AutoConfigureJsonTesters
@Import({FrameworkServiceImpl.class})
public class EnableFrameworkServiceTestBundle {
}

说明
*不需要任何方法,空类即可,好处是可以分门别类,同时如果待测试的 ServiceImpl 实现类,还缺少某个Bean,同样可以 @Import。

//..
@SpringBootTest(classes = { JpaConfig.class, EnableFrameworkServiceTestBundle.class })
//..
public class DaoTest {
 //...
}

使用容器中的 ObjectMapper

@AutoConfigureJsonTesters
  • @AutoConfigureJsonTesters 的作用之一,是让 spring-boot-test 初始化JSON有关的自动配置类:例如这个注解会导致 JacksonAutoConfiguration 启动,因此容器中就有了ObjectMapper

原理

@ImportAutoConfiguration
@PropertyMapping("spring.test.jsontesters")
public @interface AutoConfigureJsonTesters {

	/**
	 * If {@link BasicJsonTester}, {@link JacksonTester}, {@link JsonbTester} and
	 * {@link GsonTester} beans should be registered. Defaults to {@code true}.
	 * @return if tester support is enabled
	 */
	boolean enabled() default true;

}

其中 ImportAutoConfiguration 导致下方的类型初个自动装备

# AutoConfigureJsonTesters auto-configuration imports
org.springframework.boot.test.autoconfigure.json.JsonTestersAutoConfiguration
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration
org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration

TestNg 还是 Junit

TestNg
TestNg 的启动类直接改成:

@SpringBootTest(classes = {JpaConfig.class},
        webEnvironment = SpringBootTest.WebEnvironment.NONE)
@ActiveProfiles("test")
public class DaoTest extends AbstractTestNGSpringContextTests {
   //...
}

JUnit
默认就是JUnit

参考资料
[1] spring boot appendix test-auto-configuration

posted @ 2024-07-12 18:14  一杯半盏  阅读(235)  评论(0编辑  收藏  举报