Ответ 1
Использование ожиданий (или StrictExpectations)
Используя комбинацию Expectations и Deencapsulation.invoke(), вы можете частично издеваться над тестируемым объектом:
import org.junit.Test;
import static mockit.Deencapsulation.*;
import mockit.*;
public class TestAClass
{
public static class ClassToTest
{
public void methodToTest()
{
boolean returnValue = methodToMock(0);
System.out.println("methodToMock returned " + returnValue);
}
private boolean methodToMock(int value) { return true; }
}
@Tested ClassToTest classToTestInstance;
@Test
public void partiallyMockTestedClass() {
new Expectations(classToTestInstance) {{
invoke(classToTestInstance, "methodToMock", anyInt);
result = false;
times = 2;
}};
classToTestInstance.methodToTest();
classToTestInstance.methodToTest();
classToTestInstance.methodToTest();
}
}
Тест выше печатает:
methodToMock returned false
methodToMock returned false
methodToMock returned true
В общем, конечно, мы должны избегать насмешек private
. Тем не менее, я нашел на практике, что иногда бывает полезно сделать это, как правило, когда у вас есть частный метод, который делает что-то нетривиальным и уже проверен другим тестом; в этом случае, издевательский, что частный метод во втором тесте (либо для другого публичного метода, либо по другому пути через один и тот же общедоступный метод) может быть значительно проще, чем настройка необходимых входов/условий.
Использование NonStrictExpectations (устаревшее в JMockit 1.23)
Так же легко написать тест с помощью NonStrictExpectations (исходная попытка OP не работала только потому, что одно и то же нестрогое ожидание было записано дважды, а вторая запись переопределила первую):
@Test
public void partiallyMockTestedClass() {
new NonStrictExpectations(classToTestInstance) {{
invoke(classToTestInstance, "methodToMock", anyInt);
returns(false, false, true);
}};
classToTestInstance.methodToTest();
classToTestInstance.methodToTest();
classToTestInstance.methodToTest();
}
Использовать делегат
Если требуется больше гибкости, мы всегда можем записать результат Delegate
:
@Test
public void partiallyMockTestedClass() {
new NonStrictExpectations(classToTestInstance) {{
invoke(classToTestInstance, "methodToMock", anyInt);
result = new Delegate() {
boolean delegate() {
boolean nextValue = ...choose next return value somehow...
return nextValue;
}
}
}};
classToTestInstance.methodToTest();
classToTestInstance.methodToTest();
classToTestInstance.methodToTest();
}