我有一个测试,其中有一组特定的值,对此组中的每个值,两种不同的方法将执行一次。我需要检查是否以相对于彼此的特定顺序(而不是相对于值集的顺序)调用了这两种方法。例如:
String[] values = { "A", "B", "C" };
for (...<loop over values...) {
methodOne(value);
methodTwo(value);
}
values
的顺序无关紧要,但是我需要验证集合中的每个值都调用了methodOne()
和methodTwo()
,并且总是在methodOne()
之前调用methodTwo()
。我知道我可以创建一个控件并为每个值期望
methodOne()
和methodTwo()
,然后执行control.verify()
,但这取决于values
是否处于特定顺序。有没有一种优雅的方法可以做到这一点?
谢谢
最佳答案
您可以使用andAnswer()
执行此操作。
基本上,在andAnswer()
的methodOne()
内部,设置一些变量以保存传入的value
是什么。
然后在andAnswer()
的methodTwo()
中,您断言相同的参数与您从methodOne答案中保存的参数匹配。
由于每次调用methodOne
都会修改此变量,因此可以确保在methodOne()之后始终调用methodTwo()。
请注意,此解决方案不是线程安全的
首先,您需要一些东西来保存methodOne调用中的变量。这可以是具有单个字段的简单类,甚至可以是一个元素的数组。您需要这个包装器对象,因为您需要在IAnswer中引用它,它需要一个final或有效的final字段。
private class CurrentValue{
private String methodOneArg;
}
现在您的期望。在这里,我调用了您正在测试的类(被测系统)
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()
的参数值。但是,您可能仍需要对andAnswer()
使用methodTwo()
来确保依次调用正确的值。这是使用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/