我们正在尝试定义一个 UnitTest,我们在其中模拟一个对象,我在这里x
为简单起见调用它:
...
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing;
import org.kubek2k.springockito.annotations.SpringockitoContextLoader;
import org.kubek2k.springockito.annotations.WrapWithSpy;
...
@ContextConfiguration(
loader = SpringockitoContextLoader.class,
inheritLocations = true)
public class SyncServiceIntegrationTest extends AbstractIntegrationTest {
@Autowired
@WrapWithSpy
private EventDrivenIssueDeliveryConfirmer x;
...
@Before
public void setUp() {
...
doNothing().when(x).foobar(any(Event.class));
}
...
即我们希望我们的 UT(此处未显示)稍后不调用该foobar
对象上的方法x
。
奇怪的是,我们在这个 UT 类的初始化过程中得到了一个 NPE。foobar()
当传递的参数为空时,方法抛出 NPE 。
事实证明,这个带参数的调用null
发生在 -method 的行doNothing()...
中setup
,在我们的理解中,它应该只是定义模拟对象的存根。但相反,它评估any(Event.class)
显然产生的 - 表达式null
,然后它调用导致 NPE的foobar(...)
- 方法。x
除了 NullPointerException,我们还从 Mockito 收到一条错误消息:
java.lang.NullPointerException: null
... <stack trace omitted for brevity>
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Misplaced or misused argument matcher detected here:
-> at ch.sst.integration.SyncServiceIntegrationTest .setUp(SyncServiceIntegrationTest.java:69)
You cannot use argument matchers outside of verification or stubbing.
Examples of correct usage of argument matchers:
... <examples omitted for brevity>
org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
-> at ch.sst.integration.SyncServiceIntegrationTest .setUp(SyncServiceIntegrationTest.java:69)
...
为什么呢???为什么我们的存根被认为是“未完成的”?我们在这里缺少什么?
后期补充:
这个问题似乎与类
EventDrivenIssueDeliveryConfirmer
用@Transactional 标记的事实有关。删除/评论让 UT 成功。但这当然不是解决方法——我们需要那个注释。至少这提供了搜索方向的提示。@Transactional 引起的包装和 Mockito 完成的包装似乎在这里踩到了对方的脚。