在对较为复杂的service层进行单元测试时,会依赖很多其他业务产生的数据,从而造成测试方法或用例的不可重复执行。因此使用挡板来模拟dao层返回的数据将节省很多时间。
测试类的创建
@RunWith(SpringRunner.class)
@SpringBootTest
public class MyServiceTest {
@Autowired
MyService myService;
@MockBean
private MyMapper myMapper;
}
创建测试类的方法与一般步骤相同,由于需要引入挡板,因此不同之处在于需要模拟一个该service依赖的dao实例。@MockBean
标注的类的模拟实例将会替代从spring容器中获取的真实实例。
测试方法的编写
TOilTank oilTank = new TOilTank();
oilTank.setId(1L);
oilTank.setStatus(0);
Mockito.when(oilTankMapper.selectByPrimaryKey(Mockito.anyLong())).thenReturn(oilTank);
Assert.assertEquals(oilTank, oilTankService.getOilTankById(1L));
使用Mockito
的when()
和thenReturn()
来指定模拟dao实例在执行指定方法时的返回,这里返回的是创建的假数据。参数可以Mockito
的any
指定类型,从而传入任意该类型的参数都会返回结果。
使用@Mock
还是@MockBean
使用@Mock
标注与Mockito.mock(MyService.class)
是等效的,单纯用来模拟某个类并记录其行为,与spring没有关系,不会去获取spring上下文信息。@MockBean
标注的类则会与spring容器产生关联,比如上面例子中要测试的service使用@Autowired
标注,表明该类将从spring容器中获取。这个类中会依赖其他容器中的service或者mapper,如果使用@Mock
来模拟他们是无效的,因为该注解模拟的实例不会替换spring容器中的实例。使用@MockBean
可以解决这一问题。但是@MockBean
也有缺陷,每次执行测试方法时都会启动spring导致时间过长,因此当需要模拟非spring容器实例的时候优先@Mock
。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。