Springboot单元测试小试牛刀与注解介绍

这是我参与新手入门的第1篇文章

单元测试是对程序中的某个函数、某个模块的功能进行测试的代码,一般是由开发在开发代码时写的,通过单元测试,能够将代码逻辑的bug尽早的暴露出来,在较小的粒度下保证代码的正确性。

不知道你有没有听说过测试驱动开发TDD:“Test-driven Development”,TDD将单元测试视为编码的第一步,首先完成一个单元测试的代码,由于功能代码的缺失,测试会失败,甚至编译都无法通过;然后开发功能代码,知道刚刚写的单元测试通过;接着再写下一个功能的测试代码,就这样反复迭代,知道完成编码。

我个人觉得TDD是一个很好的开发流程,能够保证单元测试的覆盖率,但是TDD在实际实践的过程中会发现难度比较大,我个人习惯是先写完功能逻辑,然后再写单元测试进行测试 : )

下面我为大家介绍一下在Spring Boot工程中如何编写单元测试,对我们写的功能代码进行测试。

Spring Boot Test配置

  • Spring boot项目配置

    首先在Spring boot的工程中加入spring-boot-starter-test的依赖,在spring boot 2.4之后,spring-boot-starter-test依赖Junit5,如果还想使用Junit4的话,可以为Junit4单独添加依赖

    Maven pom.xml:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.vintage</groupId>
        <artifactId>junit-vintage-engine</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.hamcrest</groupId>
                <artifactId>hamcrest-core</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    复制代码

    Gradle build.gradle:

    testCompile 'org.springframework.boot:spring-boot-starter-test'
    testCompile group: 'junit', name: 'junit', version: '4.12'
    复制代码

Spring Boot测试Demo

假设我们的Spring Boot工程中有一个AddServer,实现了两个数字的相加,其接口和实现如下:

public interface AddService {
  long add(long a, long b);
}

@Service
public class AddServiceImpl implements AddService {
  public long add(long a, long b) {
    return a + b;
  }
}
复制代码

对add方法的测试类如下:

@RunWith(SpringRunner.class)
@SpringBootTest
public class AddServiceTest {
	@Autowired
	private AddService addService;
	
	@Test
	private void addTest(){
		Assert.assertEquals(2, addService.add(1,1));
	}
}
复制代码

@RunWith(SpringRunner.class)提供了 Spring Boot 测试特性和 JUnit 之间的桥梁。每当我们在 JUnit 测试中使用任何 Spring Boot 测试功能时,都需要此注释。

@SpringBootTest将启用应用程序中完整的context,任何一个Spring容器管理的Bean都可以注入到测试中,例如上面的Service组件AddServiceImpl就被注入到addService中。

@Test注解是Junit的注解,表示该方法是测试方法。

Assert.assertEquals是Junit提供的断言,通过断言对程序的输出结果进行判断是否符合预期,类似的断言还有如下几个:

  • assertTrue
  • assertFalse
  • assertNotEquals
  • assertArrayEquals
  • assertNull
  • assertNotNull
  • assertSame
  • assertNotSame

其含义如字面,按需使用就好

Spring Boot测试之注解

测试类上的注解可以分为几类:

  • @RunWith(SpringRunner.class)
  • @SpringBootTest等@xxxxTest
  • @AutoConfigureXXXX等

@RunWith(SpringRunner.class)前面介绍了,提供了 Spring Boot 测试特性和 JUnit 之间的桥梁,测试中使用到Spring boot的功能的都要使用该注解修饰

@SpringBootTest等@xxxxTest

所有的@xxxTest注解都被@BootstrapWith注解,它们可以启动ApplicationContext,是测试的入口,所有的测试类必须声明一个@xxTest注解。

  • @SpringBootTest 自动侦测并加载@SpringBootApplication或@SpringBootConfiguration中的配置,默认web环境为MOCK,不监听任务端口
  • @DataRedisTest 测试对Redis操作,自动扫描被@RedisHash描述的类,并配置Spring Data Redis的库
  • @DataJpaTest 测试基于JPA的数据库操作,同时提供了TestEntityManager替代JPA的EntityManager
  • @DataJdbcTest 测试基于Spring Data JDBC的数据库操作
  • @JsonTest 测试JSON的序列化和反序列化
  • @WebMvcTest 测试Spring MVC中的controllers
  • @WebFluxTest 测试Spring WebFlux中的controllers
  • @RestClientTest 测试对REST客户端的操作
  • @DataLdapTest 测试对LDAP的操作
  • @DataMongoTest 测试对MongoDB的操作
  • @DataNeo4jTest 测试对Neo4j的操作

通常情况下使用@SpringBootTest即可,可以扫描到工程中所有Spring配置,其他的有需要的,可以通过下面的AutoConfigurexxx的注解再添加相应的配置

@AutoConfigureXXXX等

  • @AutoConfigureJdbc 自动配置JDBC
  • @AutoConfigureCache 自动配置缓存
  • @AutoConfigureDataLdap 自动配置LDAP
  • @AutoConfigureJson 自动配置JSON
  • @AutoConfigureJsonTesters 自动配置JsonTester
  • @AutoConfigureDataJpa 自动配置JPA
  • @AutoConfigureTestEntityManager 自动配置TestEntityManager
  • @AutoConfigureRestDocs 自动配置Rest Docs
  • @AutoConfigureMockRestServiceServer 自动配置 MockRestServiceServer
  • @AutoConfigureWebClient 自动配置 WebClient
  • @AutoConfigureWebFlux 自动配置 WebFlux
  • @AutoConfigureWebTestClient 自动配置 WebTestClient
  • @AutoConfigureMockMvc 自动配置 MockMvc
  • @AutoConfigureWebMvc 自动配置WebMvc
  • @AutoConfigureDataNeo4j 自动配置 Neo4j
  • @AutoConfigureDataRedis 自动配置 Redis
  • @AutoConfigureJooq 自动配置 Jooq
  • @AutoConfigureTestDatabase 自动配置Test Database,可以使用内存数据库

这些注解可以搭配@xxxTest使用,用于开启在@xxxTest中未自动配置的功能。例如@SpringBootTest@AutoConfigureMockMvc组合后,就可以注入org.springframework.test.web.servlet.MockMvc

小结

Spring Boot Test为我们提供了较为方便的单元测试工具,可以方便的获取我们在程序中配置的Bean,除此之外,还提供了Mock功能和WebMvc测试、MockMvc等功能,配合JsonPath Expressions可以对collector层、service层进行方便的单元测试,这些我们下次再进行介绍。