以前的项目中,后端项目的单元测试都是构造出相应的数据然后存入数据库中,这种方式,在功能简单时还好,当功能趋于复杂时,就需要花费大量的时间去构造实验数据,前段时间,潘老师找到了一种新的单元测试方式——使用Mockito
。前两天作出了第一次尝试,期间遇到了一些问题,在询问潘老师后得到了解决,在此记录一番。
如何使用
使用方法可以看这篇文章。
Invalid use of argument matchers!
开始时使用的
Mockito.when(scoreServiceSpy.
getAllFailScoreByPage(Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong(), Mockito.any(Pageable.class))).thenReturn(mockScorePage);
使用的时候,会出现如下错误。
解决办法在错误中也已经给出,当使用matchers,所有的参数都需要提供为matcher
但是我上面的方法中确实所有的都是用的matcher呀,继续看潘老师的教程,
尝试切换成
doReturn().when()
不过在这里又犯了一个粗心的错误……
// 我写的代码
Mockito.doReturn(mockScorePage).when(scoreServiceSpy
.getAllFailScoreByPage(Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong(), Mockito.any(Pageable.class)));
// 正确的代码
Mockito.doReturn(mockScorePage).when(scoreServiceSpy)
.getAllFailScoreByPage(Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong(), Mockito.any(Pageable.class));
括号
的位置错了!
开始时,发现这个也错,以为问题不在这,而是写法有问题,翻来覆去找都没找到问题,只能求助于潘老师了。
经过潘老师的讲解,总算明白了。
首先,我们需要明白两种写法的区别
doReturn().when()与when().thenReturn()
潘老师在教程中已经提供了延伸阅读,只是当时还没来得及看。
官方的说法
doReturn().when()是无副作用的。
when().thenReturn()是有副作用的
上述说法可以这么理解:
使用Mockito.when(scoreServiceSpy.getAllFailScoreByPage(xxx)),
scoreServiceSpy.getAllFailScoreByPage(xxx)这个方法就会真正的被执行。
而使用Mockito.doReturn(mockScorePage).when(scoreServiceSpy).getAllFailScoreByPage(xxxx)时,后面的方法并不会执行。
到这也大概明白了上面出现问题的原因。
进入getAllFails()里面。
可以看到findAll()有两个参数,其中pageable是通过matcher生成的,specification不是。
Unfinished stubbing detected here:
问题还没有完全解决。
出现这个的原因,潘老师猜测是因为第三条,因为在单元测试中使用了@MockBean,通过这个注入的对象有几个特点:
- 是全局的
- 该对象有原对象的所有方法,但方法没有功能。
- 调用有返回值的方法时,若没有通过Mockito设置返回值,就会出现上述错误。
所以,出现上述错误的原因可能是
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。