为什么单测要使用Mock工具
单元测试是要遵守可重复执行,故测试用例不应该依赖外部环境以及下游服务,避免不必要的问题;
Mock工具就是为了满足这一需求的,它可以帮我们mock(模仿)出外部依赖对象,这样我们的测试用例不依赖于下游服务的状态,同时可以自主控制方法的返回值,或者执行特定行为甚至返回异常。
为什么单测要使用PowerMock
首先,PowerMock就是Mock的一种实现工具库框架,类似的还有EasyMock、Mockito,但PowerMock更为强大,除了可以满足其他工具的mock功能,其还可以mock静态、final、私有方法等,是对EasyMock、Mockito的扩展。
主要注解
@RunWith(PowerMockRunner.class)
@prepareForTest({MyObject.class})
//@PrepareForTest注解和@RunWith注解是结合使用的,单独使用@PrepareForTest不起作用。
//这两个注解就是表示你要mock一些类的静态、private、final方法,需要mock的类就在@prepareForTest中声明,@RunWith就是申明要用PowerMock环境启动
//创建一个实例,即要测试的类,不是mock
@InjectMocks
private MyServiceImpl applyTaskService;
//需要mock的服务
@Mock
private OtherService taskManageService;
实践
@Test
public void createTaskTest() throws CustomException {
//mock调用普通方法
Mockito.when(otherService.publishTask(Mockito.any(ArrayList.class))).thenReturn(new HashMap());
//mock调用静态方法,final类似
PowerMockito.mockStatic(MyObject.class);
PowerMockito.when(MyObject.staticMethod(userId)).thenReturn(0L);
//验证测试结果
Assert.assertEquals(myService.createTask(task).getMessage(), "succ");
}
@Test
public void createTaskTest() throws CustomException {
//mock调用普通方法
Mockito.when(otherService.publishTask(Mockito.any(ArrayList.class))).thenReturn(new HashMap());
//mock调用privete方法
MyObject myObject = PowerMockito.mock(MyObject.class);
PowerMockito.when(myObject.callPrivateMethod()).thenCallRealMethod();
PowerMockito.when(myObject, "privateMethodName").thenReturn(true);
//验证测试结果
Assert.assertEquals(myService.createTask(task).getMessage(), "succ");
}