我有一个测试,其中我有一组特定值,两种不同的方法将针对该组中的每个值执行一次。我需要检查这两种方法是否以相对于彼此的特定顺序调用,但与值集的顺序无关。例如:
String[] values = { "A", "B", "C" };
for (...<loop over values...) {
methodOne(value);
methodTwo(value);
}
values
的顺序无关紧要,但我需要验证是否调用了 methodOne()
和 methodTwo()
集合中的每个值以及 methodOne()
总是在 methodTwo()
之前调用。
我知道我可以创建一个控件并为每个值期望 methodOne()
和 methodTwo()
,然后执行 control.verify()
,但这取决于 values
的特定顺序。
有没有一种优雅的方式来做到这一点?
谢谢
最佳答案
您可以使用 andAnswer()
来做到这一点。
基本上,在 methodOne()
的 andAnswer()
中,您设置了一些变量来保存传入的 value
是什么。
然后在 methodTwo()
的 andAnswer()
中,您断言相同的参数与您从 methodOne 答案中保存的内容匹配。
因为每次调用 methodOne
都会修改这个变量,所以会确保 methodTwo() 总是在 methodOne() 之后调用。
注意这个解决方案不是线程安全的
首先,您需要一些东西来保存 methodOne 调用中的变量。这可以是具有单个字段的简单类,甚至可以是一个元素的数组。您需要这个包装器对象,因为您需要在 IAnswer 中引用它,而 IAnswer 需要一个 final 或有效的 final 字段。
private class CurrentValue{
private String methodOneArg;
}
现在您的期望。在这里我调用了你正在测试的类(The System Under Test)sut
:
String[] values = new String[]{"A", "B", "C"};
final CurrentValue currentValue = new CurrentValue();
sut.methodOne(isA(String.class));
expectLastCall().andAnswer(new IAnswer<Void>() {
@Override
public Void answer() throws Throwable {
//save the parameter passed in to our holder object
currentValue.methodOneArg =(String) EasyMock.getCurrentArguments()[0];
return null;
}
}).times(values.length); // do this once for every element in values
sut.methodTwo(isA(String.class));
expectLastCall().andAnswer(new IAnswer<Void>() {
@Override
public Void answer() throws Throwable {
String value =(String) EasyMock.getCurrentArguments()[0];
//check to make sure the parameter matches the
//the most recent call to methodOne()
assertEquals(currentValue.methodOneArg, value);
return null;
}
}).times(values.length); // do this once for every element in values
replay(sut);
... //do your test
verify(sut);
编辑
您是正确的,如果您使用的是 EasyMock 2.4 +,则可以使用新的 Capture
类以更简洁的方式为 methodOne()
获取参数值。但是,您可能仍需要为 methodTwo()
使用 andAnswer()
以确保按顺序调用正确的值。
这是使用 Capture 的相同代码
Capture<String> captureArg = new Capture<>();
sut.methodOne(and(capture(captureArg), isA(String.class)));
expectLastCall().times(values.length);
sut.methodTwo(isA(String.class));
expectLastCall().andAnswer(new IAnswer<Void>() {
@Override
public Void answer() throws Throwable {
String value =(String) EasyMock.getCurrentArguments()[0];
assertEquals(captureArg.getValue(), value);
return null;
}
}).times(values.length);
replay(sut);
关于java - EasyMock:如何在集合顺序无关紧要的情况下验证值集合的方法顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29176953/