平时写单测时,对于一些有限制或因当前环境无法访问的接口时,需要用到Mock来为目标接口添加自定义的实现,使其表现出我们希望表现的逻辑,从而不影响单元测试的实现。Mockito是常用的一个类库,使用也比较简单。使用分为注解的方式和直接创建对象的方式。
- 注解的方式
// 被注入的目标对象
@InjectMocks
private AimService aimService;
// 创建一个MockedService的一个mock对象
@Mock
private MockedService mockedService;
// 具体使用
{
// 激活注解
MockitoAnnotations.initMocks(this);
// 设置mock对象的指定方法预期的返回结果
Mockito.when(mockedService.getName).thenReturn("tiang");
}
- 直接创建对象
// 创建Mock对象
MockedService mockedService = Mockito.mock(MockedService.class);
// set方法
aimService.setMockedService(mockedService);
// 设置预期结果
Mockito.when(mockedService.getName).thenReturn("tiang");
注解
对于注解的实现方式,首先initMocks方法会扫描整个类中的所有字段,寻找带注解的字段。
// org.mockito.internal.configuration.InjectingAnnotationEngine#process
public void process(Class<?> clazz, Object testInstance) {
// 为所有带@Mock注解的字段生成Mock对象
processIndependentAnnotations(testInstance.getClass(), testInstance);
// 为所有带@InjectMock注解的字段,注入需要的mock对象
injectMocks(testInstance);
}
private void processIndependentAnnotations(final Class<?> clazz, final Object testInstance) {
Class<?> classContext = clazz;
while (classContext != Object.class) {
//this will create @Mocks, @Captors, etc:
delegate.process(classContext, testInstance);
//this will create @Spies:
spyAnnotationEngine.process(classContext, testInstance);
classContext = classContext.getSuperclass();
}
}
public void injectMocks(final Object testClassInstance) {
Class<?> clazz = testClassInstance.getClass();
Set<Field> mock