您是在嘲笑内部嵌套嘲笑。
getSomeList()在完成对的模拟之前,您正在呼叫,它会进行一些模拟
MyMainModel。执行此操作时,Mockito不喜欢它。
更换
@Testpublic myTest(){ MyMainModel mainModel = Mockito.mock(MyMainModel.class); Mockito.when(mainModel.getList()).thenReturn(getSomeList()); --> Line 355}与
@Testpublic myTest(){ MyMainModel mainModel = Mockito.mock(MyMainModel.class); List<SomeModel> someModelList = getSomeList(); Mockito.when(mainModel.getList()).thenReturn(someModelList);}要了解为什么这会导致问题,您需要稍微了解Mockito的工作方式,并且还需要知道Java中表达式和语句按什么顺序求值。
Mockito无法读取您的源代码,因此为了弄清楚您要执行的操作,它在很大程度上取决于静态状态。在模拟对象上调用方法时,Mockito会在内部调用列表中记录调用的详细信息。该
when方法从列表中读取这些调用中的最后一个,并将此调用记录在
OngoingStubbing它返回的对象中。
线
Mockito.when(mainModel.getList()).thenReturn(someModelList);
导致与Mockito的以下交互:
- 模拟方法
mainModel.getList()
被称为 - 静态方法
when
被称为 - 在方法返回
thenReturn
的OngoingStubbing
对象上调用when
方法。
thenReturn然后,该方法可以指示通过该
OngoingStubbing方法接收到的模拟对象,以处理对该方法的任何合适的调用
getList以返回
someModelList。
实际上,由于Mockito看不到您的代码,因此您还可以按以下方式编写模拟:
mainModel.getList();Mockito.when((List<SomeModel>)null).thenReturn(someModelList);
这种样式的读起来不太清晰,特别是因为在这种情况下
null必须强制转换,但是它与Mockito产生相同的交互序列,并且将获得与上面的行相同的结果。
但是,线
Mockito.when(mainModel.getList()).thenReturn(getSomeList());
导致与Mockito的以下交互:
- 模拟方法
mainModel.getList()
被称为 - 静态方法
when
被称为 mock
在SomeModel
中创建了一个新的getSomeList()
,- 模拟方法
model.getName()
被称为
此时,Mockito感到困惑。它以为您在嘲笑
mainModel.getList(),但是现在您要告诉它您要模拟该
model.getName()方法。对于Mockito来说,您似乎正在执行以下操作:
when(mainModel.getList());// ...when(model.getName()).thenReturn(...);
这看起来很愚蠢,
Mockito因为无法确定您在做什么
mainModel.getList()。
请注意,我们尚未进行
thenReturn方法调用,因为JVM需要先评估此方法的参数,然后才能调用该方法。在这种情况下,这意味着调用该
getSomeList()方法。
通常,像Mockito一样,依靠静态是一个错误的设计决策,因为它可能导致违反“最小惊讶原则”的情况。但是,Mockito的设计确实可以进行清晰而富有表现力的嘲讽,即使有时会令人惊讶。
最后,最新版本的Mockito在上面的错误消息中增加了一行。此额外的行表示您可能正处于与此问题相同的情况:
3:在完成“ thenReturn”指令之前,您正在测试另一个模拟的行为



