在业务测试时,有时需要加载spring容器进行业务测试,通过@Autowired加载服务,@Test执行测试用例可以实现大多公开方法的测试。
但是加载Spring容器过程较长。如果不想加载整个Spring容器,可以用mock方式加载若干依赖的对象。
此外,使用mock方式可以测试类的私有方法。还可以动态改变对象中任何域的值(包括私有域)。
接入方式如下:
1. 引入依赖
<!--测试依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.1.1.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency>
2. 在测试类中mock出待测试的类实现
@InjectMocks
private someServiceImpl someService;
3. 调用mock出来的类的私有方法,设置类中的私有域。
@Injectable
CService cService;
@Test
public void someTest() {
// 设置私有域
ReflectionTestUtils.setField(someService, "variableName", variable);
// 调用(测试)目标类的私有方法
MethodResult methodResult = ReflectionTestUtils.invokeMethod(someService, "methodName", arg1, arg2);
// 设置共有、私有方法
new Expectations() {{
AService.aMethod(anyInt, any);
result = false;
Deencapsulation.invoke(BServiceImpl.class, "privateMethod", anyInt, anyInt, anyInt, any);
result = Lists.newArrayList(new BServiceTO(1));
}}
// 设置共有方法,根据不同的入参有不同返回
cService = new MockUp<CService>(CService.class) {
@Mock
Model addModel(Integer userId, Long time) {
Model m = new Model();
m.setUserId(userId);
m.setModifyTime(time);
return m;
}
}.getMockInstance();
Deencapsulation.setField(target, "cService", cService);
}
在加载某类的私有方法时,外部无法直接调用。此时可以通过ReflectionTestUtils改变对象的私有变量,调用对象的私有方法。(借用反射)