在Mockito中检测到未完成的短截线 [英] Unfinished Stubbing Detected in Mockito
问题描述
我在运行测试时遇到异常。我正在使用Mockito进行嘲弄。 Mockito图书馆提到的提示没有帮助。
org.mockito.exceptions.misusing.UnfinishedStubbingException:
未完成的存根在这里检测到:
- >在com.a.b.DomainTestFactory.myTest(DomainTestFactory.java:355)
例如thenReturn()可能会丢失。
正确存根的例子:
when(mock.isOk())。thenReturn(true);
when(mock.isOk())。thenThrow(exception);
doThrow(exception).when(mock).someVoidMethod();
提示:
1.缺少thenReturn()
2.你试图找到最终方法,你顽皮的开发人员!
at abDomainTestFactory.myTest(DomainTestFactory.java:276)
..........
来自DomainTestFactory的测试代码。当我运行以下测试时,我看到异常
@Test
public myTest(){
MyMainModel mainModel = Mockito.mock(MyMainModel.class);
Mockito.when(mainModel.getList())。thenReturn(getSomeList()); - >第355行
}
私人列表< SomeModel> getSomeList(){
SomeModel model = Mockito.mock(SomeModel.class);
Mockito.when(model.getName())。thenReturn(SomeName); - >第276行
Mockito.when(model.getAddress())。thenReturn(Address);
返回Arrays.asList(model);
}
公共类SomeModel扩展SomeInputModel {
protected String address;
protected List< SomeClass>性能;
public SomeModel(){
this.Properties = new java.util.ArrayList< SomeClass>();
}
public String getAddress(){
return this.address;
}
}
公共类SomeInputModel {
public NetworkInputModel(){
this.Properties = new java。 util.ArrayList< SomeClass的>();
}
protected String Name;
protected List< SomeClass>性能;
public String getName(){
return this.Name;
}
public void setName(String value){
this.Name = value;
}
}
你在模仿中嵌套嘲弄。在完成 MyMainModel
的模拟之前,你正在调用 getSomeList()
,这会做一些模拟。当你这样做时,Mockito不喜欢它。
替换
@Test
public myTest(){
MyMainModel mainModel = Mockito.mock(MyMainModel.class);
Mockito.when(mainModel.getList())。thenReturn(getSomeList()); - > 355行
}
@Test
public myTest(){
MyMainModel mainModel = Mockito.mock(MyMainModel.class);
列表< SomeModel> someModelList = getSomeList();
Mockito.when(mainModel.getList())。thenReturn(someModelList);
}
要了解导致问题的原因,您需要了解一些如何Mockito工作,也知道用Java评估表达式和语句的顺序。
Mockito无法读取你的源代码,所以为了弄明白你是什么它要求它做,它依赖于静态。当您在模拟对象上调用方法时,Mockito会在内部调用列表中记录调用的详细信息。当方法从列表中读取最后一个这样的调用时, 该行 导致以下与Mockito的互动: 事实上,由于Mockito不能看到你的代码,你也可以按如下方式编写你的模拟: 这种风格不太清楚,特别是因为在这种情况下 但是,行 导致以下与Mockito的互动: 此时Mockito感到困惑。它以为你在嘲笑 对于 注意我们没有得到到 一般来说,依赖它是一个糟糕的设计决策在静态上,正如Mockito所做的那样,因为它可能导致违反最小惊讶原则的情况。然而,Mockito的设计确实会产生清晰而富有表现力的嘲讽,即使它有时会让人感到惊讶。 最后,最近版本的Mockito在上面的错误信息中添加了一条额外的行。这个额外的行表明你可能与这个问题处于相同的情况: 3:你在之前中存在另一个模拟行为的行为然后返回'指令完成 I am getting following exception while running the tests. I am using Mockito for mocking. The hints mentioned by Mockito library are not helping. Test Code from DomainTestFactory. When I run the following test, I see the exception
You're nesting mocking inside of mocking. You're calling Replace with To understand why this causes a problem, you need to know a little about how Mockito works, and also be aware in what order expressions and statements are evaluated in Java. Mockito can't read your source code, so in order to figure out what you are asking it to do, it relies a lot on static state. When you call a method on a mock object, Mockito records the details of the call in an internal list of invocations. The The line causes the following interactions with Mockito: The In fact, as Mockito can't see your code, you can also write your mocking as follows: This style is somewhat less clear to read, especially since in this case the However, the line causes the following interactions with Mockito: At this point Mockito gets confused. It thought you were mocking This looks silly to Note that we did not get to the Generally it is a bad design decision to rely on static state, as Mockito does, because it can lead to cases where the Principle of Least Astonishment is violated. However, Mockito's design does make for clear and expressive mocking, even if it leads to astonishment sometimes. Finally, recent versions of Mockito add an extra line to the error message above. This extra line indicates you may be in the same situation as this question: 3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed
这篇关于在Mockito中检测到未完成的短截线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!将这个调用记录在它返回的
OngoingStubbing
对象中。 / p>
Mockito.when(mainModel.getList()) .thenReturn(someModelList);
mainModel.getList()
被调用,
调用
时,
OngoingStubbing上调用
thenReturn
返回的对象。
thenReturn
方法然后可以通过 OngoingStubbing
方法指示它收到的模拟来处理对 getList
返回 someModelList
的方法。
mainModel.getList();
Mockito.when((List< SomeModel>)null).thenReturn(someModelList);
null
必须进行转换,但它会与Mockito生成相同的交互序列,并且会获得与上面一行相同的结果。
Mockito.when(mainModel.getList())。thenReturn(getSomeList());
mainModel.getList()
被调用,
当
被调用时,
模拟
SomeModel
已创建(在 getSomeList()
内),
model.getName()
被调用,
mainModel.getList()
,但是现在你告诉你要模拟 model.getName()
方法。对于Mockito,看起来你正在做以下事情:
when(mainModel.getList());
// ... ...
when(model.getName())。thenReturn(...);
Mockito
这看起来很傻不知道你在做什么 mainModel.getList()
。
thenReturn
方法调用,因为JVM需要在调用方法之前评估此方法的参数。在这种情况下,这意味着调用 getSomeList()
方法。
org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
-> at com.a.b.DomainTestFactory.myTest(DomainTestFactory.java:355)
E.g. thenReturn() may be missing.
Examples of correct stubbing:
when(mock.isOk()).thenReturn(true);
when(mock.isOk()).thenThrow(exception);
doThrow(exception).when(mock).someVoidMethod();
Hints:
1. missing thenReturn()
2. you are trying to stub a final method, you naughty developer!
at a.b.DomainTestFactory.myTest(DomainTestFactory.java:276)
..........
@Test
public myTest(){
MyMainModel mainModel = Mockito.mock(MyMainModel.class);
Mockito.when(mainModel.getList()).thenReturn(getSomeList()); --> Line 355
}
private List<SomeModel> getSomeList() {
SomeModel model = Mockito.mock(SomeModel.class);
Mockito.when(model.getName()).thenReturn("SomeName"); --> Line 276
Mockito.when(model.getAddress()).thenReturn("Address");
return Arrays.asList(model);
}
public class SomeModel extends SomeInputModel{
protected String address;
protected List<SomeClass> properties;
public SomeModel() {
this.Properties = new java.util.ArrayList<SomeClass>();
}
public String getAddress() {
return this.address;
}
}
public class SomeInputModel{
public NetworkInputModel() {
this.Properties = new java.util.ArrayList<SomeClass>();
}
protected String Name;
protected List<SomeClass> properties;
public String getName() {
return this.Name;
}
public void setName(String value) {
this.Name = value;
}
}
getSomeList()
, which does some mocking, before you've finished the mocking for MyMainModel
. Mockito doesn't like it when you do this.@Test
public myTest(){
MyMainModel mainModel = Mockito.mock(MyMainModel.class);
Mockito.when(mainModel.getList()).thenReturn(getSomeList()); --> Line 355
}
@Test
public myTest(){
MyMainModel mainModel = Mockito.mock(MyMainModel.class);
List<SomeModel> someModelList = getSomeList();
Mockito.when(mainModel.getList()).thenReturn(someModelList);
}
when
method reads the last of these invocations off the list and records this invocation in the OngoingStubbing
object it returns.Mockito.when(mainModel.getList()).thenReturn(someModelList);
mainModel.getList()
is called,when
is called,thenReturn
is called on the OngoingStubbing
object returned by the when
method.thenReturn
method can then instruct the mock it received via the OngoingStubbing
method to handle any suitable call to the getList
method to return someModelList
.mainModel.getList();
Mockito.when((List<SomeModel>)null).thenReturn(someModelList);
null
has to be casted, but it generates the same sequence of interactions with Mockito and will achieve the same result as the line above.Mockito.when(mainModel.getList()).thenReturn(getSomeList());
mainModel.getList()
is called,when
is called,mock
of SomeModel
is created (inside getSomeList()
),model.getName()
is called,mainModel.getList()
, but now you're telling it you want to mock the model.getName()
method. To Mockito, it looks like you're doing the following:when(mainModel.getList());
// ...
when(model.getName()).thenReturn(...);
Mockito
as it can't be sure what you're doing with mainModel.getList()
.thenReturn
method call, as the JVM needs to evaluate the parameters to this method before it can call the method. In this case, this means calling the getSomeList()
method.