常用mock类框架
在软件测试和开发过程中,Mock框架扮演着至关重要的角色,它们允许开发者模拟对象的行为,以便在不需要实际依赖的情况下进行测试。以下是一些常用的Mock框架:
- Mockito
- PowerMock
- EasyMock
- JMock
- Spock
初始化mock/spy对象的两种方式
- Mockito.mock(Class),Mockito.spy(Class)
- 注解方式:@Mock, @Spay
Mock对象默认返回值
mock对象默认不会调用真实方法,直接返回mock对象的默认值:
-
int
-
null(UserVo)
-
空集合(List)
参数匹配
ArgumentMatcher.any拦截任意类型的参数
除了any,还有anyXXX(anyLong,anyString…)
指定返回值
- doReturn(returnObj).when(mockObject).someMethod(someArg);
- when(mockObject.someMethod(someArg)).thenReturn(returnObj);
void返回值方法插桩
doNothing().when(mockObject).someMethod(someArg);
插桩的两种方式
- when(obj.someMethod()).thenXxx();其中obj可以是mock对象
- doXxx().when(obj).someMethod();其中obj可以是mock/spy对象
注意:
spy对象在没有插桩时是调用真实方法的,写在when…then中会导致先执行一次原方法,达不到mock的目的。
需使用doXxx().when().someMethod()的方式。
如果用到了spy,推荐使用第二种方式,或者不管是Mock还是Spy都用第二种方式。
抛出异常
- doThrow(SomeException.class).when(mockObj).someMethod();
- when(mockObj.someMethod()).thenThrow(SomeExcetion.class);
多次插桩
when(mockObj.someMethod()).thenReturn(returnObj1).thenReturn(returnObj2).then(returnObj3);
用这种流式的写法,在下面调用这个mock对象的对应的方法时会依次返回设置的返回值。
或者简写为:
when(mockObj.someMethod()).thenReturn(returnObj1,returnObj2,returnObj3);
实现指定逻辑的插桩
可以使用thenAnswer实现指定逻辑的插桩,示例如下,个人觉得这种场景比较少。
执行真正的原始方法
- mock对象默认不执行原始方法。
用when(mockObj.someMethod()).thenCallRealMethod()的方式执行原始方法。
-
spy对象默认就会调用真实的方法
-
可以不让spy对象调用真实方法
doReturn(returnObj).when(spyObj).someMethod();//指定了返回值就不用调用真实的方法了
示例:
verify的使用
- 验证调用过1次或几次
- verify(mockObj).someMethod();
验证调用过1次这个方法
- verify(mockObj, times(1)).someMethod();
此时与上面的等价,但是可以修改times()的参数值,写几就代表验证调用几次。
- 验证没有调用过
verify(mockObj, never()).someMethod();
或者
verify(mockObj, times(0)).someMethod();
- 验证最少或最多调用多少次
verify(mockObj, atLeast(1)).someMethod();
verify(mockObj, atMost(1)).someMethod();
@InjectMocks注解的使用
-
被@InjectMocks标注的属性必须是实现类,因为mockito会创建对应的实例对象
-
默认创建的对象是未经过mockito处理的普通对象,因此常配合@Spy注解使其变成默认调用真实方法的mock对象
-
被@InjectMocks标注的属性需要用到mock/spy对象,mockito会自动使用当前类里的mock或spy成员按类型或名称注入
原理:构造器注入、setter注入、字段反射注入
注意:
@InjectMocks不能注入父类的属性
几种常用的断言工具
示例:
自动生成单元测试类的插件
idea插件:squaretest插件
选择一个生成的模板:
静态方法的Mock
mock静态类的话需要释放资源,如果不释放资源的话,后面还有对这个类进行mock操作会报错