使用Mockito进行单元测试
说下背景,java单元测试想要进行mock,于是查到了这个框架,就应用了一下,遇到了一些问题记录一下。
1、想要测试Service层的类,但是Service层引用了dao层的Mapper,需要mapper进行注入,也就是说Mock一个假的mapper
抛出一个异常如下:
org.mockito.exceptions.base.MockitoException: Mockito cannot mock this class: interface com.hikvision.hikkan.contentmgr.console.mapper.ConsoleNewsMapper.Mockito can only mock non-private & non-final classes.
If you're not sure why you're getting this error, please report to the mailing list.
看原因是mock失败,搜了挺多百思不得其解?最后蛛丝马迹中,可能和jdk版本有关,切换为 1.8 错误消失。
以上问题,可以在pom中手动引入mockito框架,java11对应 2.22.0版本的mockito 是正常的。
2、使用属性注入
代码中,都是通过@Autowire进行属性注入的,https://www.tutorialspoint.com/mockito/mockito_create_mock.htm 文档中使用的是构造器注入的,可以这么写完成属性注入。
@InjectMocks 必须放在实现类上,interface上不行,我最开始用的是服务的接口,报错了
@Mock 注解说明是一个可以被注入的服务。
3、设置Mock的时候,期望返回,抛出异常,
org.mockito.exceptions.misusing.WrongTypeOfReturnValue: ConsoleNewsEntity cannot be returned by toString() toString() should return String *** If you're unsure why you're getting above error read on. Due to the nature of the syntax above problem might occur because: 1. This exception *might* occur in wrongly written multi-threaded tests. Please refer to Mockito FAQ on limitations of concurrency testing. 2. A spy is stubbed using when(spy.foo()).then() syntax. It is safer to stub spies - - with doReturn|Throw() family of methods. More in javadocs for Mockito.spy() method.
想从thenReturn 返回上面 PrimaryId 对应的是Entity实例,dbList是我预设的列表。
改成这样可以
4、mock获取方法参数的方式
如下图所示
获取update方法对应的输入参数。
5、Mockito如何对参数为null的方法进行匹配呢?
有一种情况,mock的方法,可能会失效。当参数类表中使用了Interger这样的包装类,但是传入的确是null的时候。
像我这样写,编译的时候不会报错,但是传入null作为参数的时候,此刻 userRecordService.searchHistoryInfo 就会返回null 。并非我们自己的设置的值。
要想让他匹配到null值可以做如下处理。使用 Mockito.IsNull() 替换