method2() 不属于你模拟的类型。它属于method1() 返回的类型。您只能告诉模拟在调用 method1() 时要返回什么(这就是异常包名称中 misusing 部分的原因)。
理论上,您可以为method1() 返回的类型创建一个模拟,并指示mockedClass 返回第二个模拟,然后在调用method2() 时告诉新模拟返回x。但是,出于多种原因,让模拟返回其他模拟通常是一个非常糟糕的主意。
在不了解您的实际代码以及您真正想要实现的目标的情况下,很难就此提供任何建议。因此,我只能提供一些一般性的提示,它们可能适用于您的情况,也可能不适用于您的情况。
通常,应避免使用object1.method1().method2() 调用链。 “告诉,不要问”原则说,应该避免向一个对象询问 something 然后对那个something 进行操作(Tell一个对象要做什么,而不是要求它自己去做)。调用链暗示 method1() 正在返回另一个对象 (object2),然后使用该对象调用 method2()。取而代之的是,您应该向object1 添加一个方法,该方法正在调用method2() 并返回其结果。简单例子:
这就是你的类的样子
public class C1 {
private C2 o2;
public C2 method1() {
return o2;
}
}
public class C2 {
public int method2() {
return computeValue();
}
}
// somewhere else:
int value = object1.method1().method2();
相反,您可以这样设计:
public class C1 {
private C2 o2;
//public C2 method1() {
// return o2;
//}
public int method3() {
return o2.method2();
}
}
public class C2 {
public int method2() {
return computeValue();
}
}
// somewhere else:
//int value = object1.method1().method2();
int value = object1.method3();
这样可以避免调用链,C1 不必透露它包含 C2 类型的值,这意味着你可以在调用者不知道的情况下更改它。
除了更好的设计和避免调用链(也称为“火车残骸”)之外,这允许您针对您的模拟情况执行以下操作:
//when(mockedClass.method1().method2()).thenReturn(x);
when(mockedClass.method3()).thenReturn(x);