我正在使用Mockito编写一个测试柜,在我看来,一个Mockito规则没有得到定义。以下是我的场景。
public class DummyTest {
private final String[] alphabet= {"a", "b", "c", "d", "e" };
private final String[] numeric= {"1", "2", "3", "4", "5" };
AtomicInteger idx;
String currentAlphabet;
String currentNumeric;
int currentIndex;
Dummy dummyObj;
private ruleSetUp() {
dummyObj = Mockito.spy(new Dummy());
// Rule for rs.next()
Mockito.doAnswer(new Answer<Boolean>() {
@Override
public Boolean answer(InvocationOnMock invocation) throws Throwable {
currentIndex = idx.getAndIncrement();
if (alphabet.length > currentIndex) {
currentAlphabet= alphabet[currentIndex];
currentNumeric= numeric[currentIndex];
return true;
} else
return false;
};
}).when(rs).next();
// Rule for rs.getInt()
Mockito.doAnswer(new Answer<Integer>() {
@Override
public Integer answer(InvocationOnMock invocation) throws Throwable {
return idx.get() - 1;
};
}).when(rs).getInt(2);
// Rule for rs.getByte()
Mockito.doAnswer(new Answer<byte[]>() {
@Override
public byte[] answer(InvocationOnMock invocation) throws Throwable {
return currentNumeric.getBytes(StandardCharsets.UTF_8);
};
}).when(rs).getBytes(1);
Mockito.doReturn(currentAplhabet).when(dummyObj).innerMethod(Mockito.anyInt(), Mockito.anyInt());
}
@Test
public void methodTest(){
ruleSetUp();
}
}
我正在测试的方法如下:
class Dummy {
public void method(int param1) {
/* some code */
param2 = xyz() ; // Some mathematical calculation
while(rs.next()) {
byte[] strByte = rs.getBytes(1);
int number = rs.getInt(2);
String str= new String(strByte, StandardCharset.UTF-8);
// TEst Case rule causes below value to be always null
String alphabet = innerMethod(param1, param2);
}
}
}
在执行此测试方法时,始终发现正在测试的方法中字母的值是无效的。根据电流数的正确值,正确填充了" str"的值。循环还运行正确的次数。
我很困惑为什么不应用Innermethd()的规则。我没有遇到任何错误,只有填充的值总是无效的,无论循环正在通过的迭代中如何。
你们能指出我出错的地方和解决方案的方法吗?
谢谢
String currentAlphabet;
private ruleSetUp() {
// [snip]
Mockito.doReturn(currentAlphabet).when(dummyObj).innerMethod(
Mockito.anyInt(), Mockito.anyInt());
}
Mockito将每个呼叫的null
返回到innerMethod
,因为您正在告诉。尽管每当调用next
时设置currentAlphabet
,但直到那时才设置任何内容。在称为ruleSetup
时,currentAlphabet
为null,因此每个呼叫innerMethod
的oblito stubs null
。
您需要将doReturn
与答案相反:
doAnswer(new Answer<String>() {
@Override public void answer(InvocationOnMock invocation) {
// This field on the test changes based on other invocations.
return currentAlphabet;
}
}).when(dummyObj).innerMethod(anyInt(), anyInt());
作为旁注,因为您要替换多种相关方法的行为,因此为了可读性和易于维护而考虑正常的覆盖:
private DummyObj createDummy() {
return new DummyObj() {
private final String[] alphabet= {"a", "b", "c", "d", "e" };
private final String[] numeric= {"1", "2", "3", "4", "5" };
AtomicInteger idx;
String currentAlphabet;
String currentNumeric;
int currentIndex;
@Override public boolean next() { /* ... */ }
@Override public int nextInt() { /* ... */ }
@Override public byte nextByte() { /* ... */ }
@Override public String innerMethod() { /* ... */ }
};
}