Java Mockito:无法doReturn子类?
当我试图模拟一个方法时,我得到了一个Java Mockito:无法doReturn子类?,java,unit-testing,mockito,Java,Unit Testing,Mockito,当我试图模拟一个方法时,我得到了一个未完成的stubingexception。我试图让doReturn返回实现特定接口的类的模拟实例。该接口是被模拟方法的原始返回类型 下面是类结构的一个示例: class A { private C obj; C getObj() { return obj; } } class B implements C { void doCStuff() {} void doBStuff() {} } inte
未完成的stubingexception
。我试图让doReturn
返回实现特定接口的类的模拟实例。该接口是被模拟方法的原始返回类型
下面是类结构的一个示例:
class A {
private C obj;
C getObj() {
return obj;
}
}
class B implements C {
void doCStuff() {}
void doBStuff() {}
}
interface C {
void doCStuff();
}
使用此结构,我试图模拟A.getObj()
,并让它返回B
的模拟实例
public void test() {
A aObj = Mockito.mock(A.class);
B bObj = Mockito.mock(B.class);
Mockito.doReturn(bObj).when(aObj).getObj(); //throws UnfinishedStubbingException
//Edit:
B newB = (B)aObj.getObj();
newB.doBStuff();
}
问题是,我需要让getObj
返回B
的模拟实例,但我不能。通常在Java中,我可以从返回类型为C
的方法以多态方式返回B
的实例,因为B
实现了C
。但是,doReturn
似乎无法返回实现原始返回类型的子类的实例
我希望我的理解是正确的,但我是做错了什么,还是有解决办法?不确定这是否有效;代码无法判断这是否会奏效,但您可以尝试以下方法:
final C c = spy(new B());
final A a = spy(new A());
doReturn(c).when(a).getObj();
更完整的答案需要更完整的问题;) 啊,我是个白痴。结果证明我试图模仿的方法是最终的,我最初没有注意到这一点。它来自一个超级班级,我认为它不是最终的。不能重写final方法,Mockito也不能模拟它们 这里有一个更好的例子:
class A extends D {
...
}
class D {
//Can't mock this.
final Object getObj() { ... }
}
事实证明,您仍然可以通过Mockito以多态方式返回对象,所以这是一个错误警报。等等。您的
.getObj()
无论如何都会返回C
,而不是B
。这可能是莫基托所困惑的…是的,但无论如何,a B是C。如果mockito不能处理正常的多态调用,这是可以理解的,但我需要一种方法来解决这个问题。为什么?调用代码只能使用C接口中定义的功能(没有不安全的向下转换)。既然你是在模仿,你无论如何也不会使用B的任何具体功能。只需返回一个模拟的C。同样,当您尝试Mockito.when(aObj.getObj())时会发生什么情况。然后返回(bObj)
?@TomG由于复杂性,我没有提供完整的示例,但本质上我最终会做bb=(B)a.getObj();b、 doBStuff()
如果我模拟C
,它将抛出一个ClassCastException
。是的,我尝试了另一种方法,结果是我得到了同样的例外。最初的问题使用的是模拟,而不是间谍——调用真实方法的默认行为在这里可能并不明显…@TomG是的,我知道;但问题中提供的代码并没有真正起到帮助作用。我只能用我所得到的信息做这么多;)我已经试过了,但没有成功。有什么额外的信息可以让这个问题变得更好?