什么是Mock?
在单元测试中,我们往往想去独立地去测一个类中的某个方法,但是这个类可不是独立的,它会去调用一些其它类的方法和service,这也就导致了以下两个问题:
外部服务可能无法在单元测试的环境中正常工作,因为它们可能需要访问数据库或者使用一些其它的外部系统。 我们的测试关注点在于这个类的实现上,外部类的一些行为可能会影响到我们对本类的测试,那也就失去了我们进行单测的意义。
为了解决这种问题,Mockito和PowerMock诞生了。这两种工具都可以用一个虚拟的对象来替换那些外部的、不容易构造的对象,便于我们进行单元测试。两者的 不同点在于Mockito对于大多数的标准单测case都很适用,而PowerMock可以去解决一些更难的问题(比如静态方法、私有方法等)。
使用示例
一、引入依赖
<!-- 默认会引入mockito-core -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 如果需要mock静态方法,私有方法,final方法引入powerMockito -->
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>2.0.0-RC.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>2.0.0-RC.3</version>
<scope>test</scope>
</dependency>
二、测试类特殊示例
@RunWith(PowerMockRunner.class) // 使用powerMockito
@PrepareForTest(TestService.class) // 对于需要使用powerMockito的类进行配置
public class RefundServiceTestCase {
@InjectMocks // 会将mock的类注入到该类
private TestService testService;
@Mock // mock该类,会拦截所有方法调用, 使用when(obj.do()).doReturn();
private Test2Service test2Service;
@Spy // mock该类,部分mock,没有mock的方法直接调用真实方法,最好使用doReturn()..when(obj).do(), 如果使用when(obj.do()).doReturn()仍然会调用真实方法,只是最后会返回mock的结果
private Test test;
@Test
public void test() throws Exception {
// mock接口配置
// 如果需要mock私有方法,必须这样写一下
testService = PowerMockito.spy(testService);
// mock私有方法
PowerMockito.doReturn(null)
.when(testService, "test", any(), any());
when(test2Service.test2(anyString(), eq(1)))
.thenReturn(testObject);
// 调用mock接口
TestObject testObject = testService.test("test", 1, 2);
Assert.assertNotNull(testObject);
Test2Object test2Ojbect = testService2.test2("test2", 1);
Assert.assertNotNull(test2Object);
}