1.Powermockito和Mockito是什么?
Mocktio和PowerMockito都是Mock的工具类,主要是Java的类库,Mock就是伪装的意思。
他们适用于单元测试中,对于单元测试来说,我们不希望依赖于第三方的组件,比如数据库、Webservice等。在写单元测试的时候,我们如果遇到了这些需要依赖第三方的情况,我们可以使用Mock的技术,伪造出来我们自己想要的结果。
对于Java而言,mock的对象主要是Java 方法和 Java类。
2.Powermockito和Mockito的区别
PowerMockito是Mockito的一种增强,他们的PowerMockito可以调用Mockito的方法,但是对于Mocktio不能Mock的对象或者方法,我们可以使用PowerMockito来实现。
比如Mockito不能用于static Method, final method, 枚举类, private method,这些我们都可以用PowerMockito来实现,当PowerMockito和mockito结合使用的时候,我们需要考虑兼容性的问题。
3.两者的版本兼容
Mockito | PowerMockito |
---|---|
2.8.9+ | 2.x |
2.8.0-2.8.9 | 1.7.x |
2.7.5 | 1.7.0RC4 |
2.4.0 | 1.7.0RC2 |
2.0.0-beta - 2.0.42-beta | 1.6.5-1.7.0RC |
1.10.8 - 1.10.x | 1.6.2 - 2.0 |
1.9.5-rc1 - 1.9.5 | 1.5.0 - 1.5.6 |
1.9.0-rc1 & 1.9.0 | 1.4.10 - 1.4.12 |
1.8.5 | 1.3.9 - 1.4.9 |
1.8.4 | 1.3.7 & 1.3.8 |
1.8.3 | 1.3.6 |
1.8.1 & 1.8.2 | 1.3.5 |
1.8 | 1.3 |
1.7 | 1.2.5 |
附上对应github地址:mock
4.Powermockito和Mockito常用的一些语法和关键词
@RunWith(PowerMockRunner.class) | 代表使用的powerMock作为启动类 |
@PrepareForTest(Static.class) | 如果需要mock静态的方法和静态的类需要使用 |
@Mock | mock修饰的类(类似于spring的@Resource),不会调用原方法 |
@Spy | 为现有的对象进行打桩(具体可以干啥,后面的博客会有介绍,这里只需要记住,这个比较常用即可),会调用原方法 |
@InjectMocks | 会将mock和spy的对象注入到InjectMocks修饰的类里面类似于spring的@Service,会调用原方法 |
PowerMockito.mockStatic(HttpClientUtils.class) | 和PrepareForTest(Static.class) 一起使用,用于mock静态的类和方法 |
MockitoAnnotations.initMocks(this); | 初始化mock的对象 |
when(mockService.get(anyString()).thenReturn(1); |
真正进行mock的语法可以,可以理解为(当做了什么事情,然后得到了什么结果) |
PowerMockito.doReturn(1).when(mockService).get(any()); |
真正进行mock的语法可以,可以理解为(拿到什么结果,当做什么事情的时候) |
Mockito.verify(mockService, Mockito.times(1)).get(any()); |
这里是验证当前方法执行的次数 |
5.简单写一个mock单元测试的脚手架
@RunWith(PowerMockRunner.class)
public class MockServiceTest {
@InjectMocks
private MockService mockService;
@Mock
private MockDAO mockDAO;
@Before
public void init() {
MockitoAnnotations.initMocks(this);
}
@Test
public void testGetIOSAppDetailByParams() {
// Give
long userId = 1l;
long expectedUserId = 1l;
// When
PowerMockito.when(mockDAO.getById(anyLong())).thenReturn(new UserInfo());
UserInfo user = mockService.getById(userId);
// Then
assertThat(user.getId()).isEqualTo(expectedUserId);
}
}
5.使用mock进行单元测试的注意事项
- 单测代码不允许出行System.out.println();
- 单元测试必须是可重复、独立运行、自动化的
- 单元测试必须要有验证逻辑,也就是Then这个阶段,要不然就是快乐单测,没有实际用处