Java Mockito模拟调用两次的方法调用
我试图用mockito来模拟一个方法。然而,我正在注入mock的类在发送相同类型的两个不同对象时两次调用该方法,但取决于对象中的值来确定该方法的输出 举个例子,如果我想嘲笑Java Mockito模拟调用两次的方法调用,java,unit-testing,junit,mockito,springmockito,Java,Unit Testing,Junit,Mockito,Springmockito,我试图用mockito来模拟一个方法。然而,我正在注入mock的类在发送相同类型的两个不同对象时两次调用该方法,但取决于对象中的值来确定该方法的输出 举个例子,如果我想嘲笑 public ArrayList<example> attemptToMock(testObject testing) public ArrayList attemptomock(测试对象测试) 让sat类型testObject包含一个字符串值 因此,如果testObject中的字符串值为“OK”,则atte
public ArrayList<example> attemptToMock(testObject testing)
public ArrayList attemptomock(测试对象测试)
让sat类型testObject
包含一个字符串值
因此,如果testObject中的字符串值为“OK”,则attemptomock
应在其中输出两个对象的数组。如果testObject
字符串值为“否”,则发出的数组列表只有一个对象
如何编写一个测试来处理一个调用,这样一个类就可以在同一个方法中调用
attemptomock
两次,并且可以根据testObject
中的值模拟它的输出。我可以模拟它来发送不同的数组。您可以访问传递到模拟方法调用中的参数,并使用应答接口相应地改变返回值。请参见,和的答案
基本上,这里发生的唯一奇怪/不明显的事情是,您必须将参数向下转换为您期望的类型。因此,在您的例子中,如果您正在模拟一个采用单个“TestObject”参数的方法,那么您必须在“answer”实现中执行类似的操作:
Object[] args = invocation.getArguments();
TestObject testObj = (TestObject) args[0];
if ("OK".equals(testObj.value)) {
return new ArrayList(value1, value2);
} else if ("NO".equals(testObj.value)) {
return new ArrayList(singleObject);
}
有几个选择:
- 在您的对象(TestObject)上。只有当对象上的所有值都是可预测的,并且可能比其他解决方案更费工时,这才是可行的,但如果您仍然需要编写
和equals
(例如,对于映射和设置行为),这是一个合理的解决方案hashCode
// Mockito compares with objects' equals(Object) methods by default. when(collaborator.attemptToMock(object1)).thenReturn(array1); when(collaborator.attemptToMock(object2)).thenReturn(array2);
- 编写一个数组,并使用它来匹配数组。对于特定的情况,这可以作为
的紧凑模拟,如果您需要在许多测试中基于相同的值更改行为,那么它尤其方便equals
public class IsATestObjectWithValue extends TypeSafeMatcher<TestObject> { private final String expectedValue; public IsATestObjectWithValue(String expectedValue) { super(TestObject.class); this.expectedValue = expectedValue; } @Override public void matchesSafely(TestObject object) { // object will never be null, but object.value might. return expectedValue.equals(object.value); } }
- 使用答案。匿名的内部答案很常见,也很简洁,你可以访问所有的论点。这对于一次性解决方案尤其有用,或者如果您希望在传入无效值(testObject.value)时显式且立即使测试失败
- 最后,如果调用的顺序是可预测的,则可以按顺序返回多个值
对于第一次调用,上述任一行都将返回when(collaborator.attemptToMock(any(TestObject.class))) .thenReturn(array1).thenReturn(array2); when(collaborator.attemptToMock(any(TestObject.class))) .thenReturn(array1, array2); // equivalent
;对于第二次调用以及之后的所有调用,无论参数如何,都将返回array1
。此解决方案将比原始问题所要求的更为脆弱,如果调用顺序发生变化,或者如果其中任何一个调用被删除或重复,则此解决方案将失败。但是,如果测试是非常临时的,或者如果顺序是绝对固定的,则此解决方案有时是最紧凑的解决方案array2
when(collaborator.attemptToMock(any(TestObject.class)))
.thenReturn(array1).thenReturn(array2);
when(collaborator.attemptToMock(any(TestObject.class)))
.thenReturn(array1, array2); // equivalent