我们可以指定明确的参数匹配条件,或者使用模式匹配:
@RunWith(SpringRunner.class) @SpringBootTest public class MathServiceTest { @Configuration static class ConfigTest {} @MockBean private MathService mathService; @Test public void testDivide() { Mockito.when(mathService.divide(4, 2)) .thenReturn(2); Mockito.when(mathService.divide(8, 2)) .thenReturn(4); Mockito.when(mathService.divide(Mockito.anyInt(), Mockito.eq(0))) // 必须同时用模式 .thenThrow(new RuntimeException("error")); Assertions.assertThat(mathService.divide(4, 2)) .isEqualTo(2); Assertions.assertThat(mathService.divide(8, 2)) .isEqualTo(4); Assertions.assertThatExceptionOfType(RuntimeException.class) .isThrownBy(() -> { mathService.divide(3, 0); }) .withMessageContaining("error"); } }上面的测试可能有些奇怪,mock的对象也同时作为测试的目标。这是因为我们的目的在于介绍mock,所以简化了测试流程。
注意,如果我们对方法的其中一个参数使用了模式,其他的参数都需要使用模式。比如下面这句:
Mockito.when(mathService.divide(Mockito.anyInt(), Mockito.eq(0))),我们的本意是Mockito.when(mathService.divide(Mockito.anyInt(), 0)),但是我们不得不为第二个参数使用模式。
附录 相关注解的汇总 注解 说明@RunWith junit的注解,通过这个注解使用SpringRunner.class,能够将junit和spring进行集成。后续的spring相关注解才会起效。
@SpringBootTest spring的注解,通过扫描应用程序中的配置来构建测试用的Spring上下文。
@AutoConfigureMockMvc spring的注解,能够自动配置MockMvc对象实例,用来在模拟测试环境中发送http请求。
@WebMvcTest spring的注解,切片测试的一种。使之替换@SpringBootTest能将构建bean的范围限定于web层,但是web层的下层依赖bean,需要通过mock来模拟。也可以通过参数指定只实例化web层的某一个到多个controller。具体可参考。
@RestClientTest spring的注解,切片测试的一种。如果应用程序作为客户端访问其他Rest服务,可以通过这个注解来测试客户端的功能。具体参考。
@MybatisTest mybatis按照spring的习惯开发的注解,切片测试的一种。使之替换@SpringBootTest,能够将构建bean的返回限定于mybatis-mapper层。具体可参考mybatis-spring-boot-test-autoconfigure。
@JdbcTest spring的注解,切片测试的一种。如果应用程序中使用Jdbc作为持久层(spring的JdbcTemplate),那么可以使用该注解代替@SpringBootTest,限定bean的构建范围。官方参考资料有限,可自行网上查找资料。
@DataJpaTest spring的注解,切片测试的一种。如果使用Jpa作为持久层技术,可以使用这个注解,参考。
@DataRedisTest spring的注解,切片测试的一种。具体内容参考。
参考资料
Spring Boot Testing
Spring Boot Test博客
Mybatis Spring Boot Test官方资料
深入探討 Test Double、Dummy、Fake、Stub 、Mock 與 Spy
单元测试,集成测试概念与各种工具介绍