JMockit: как переопределить уже издевавшийся метод новым издевательством?
Я думаю, что, возможно, нашел ошибку в JMockit, но я хотел бы, чтобы некоторые подтвердили, является ли это ошибкой или есть что-то, что я упускаю.
У меня есть следующий (очень простой) класс:
public class Dummy {
public void foo() {System.out.println("O");}
}
Теперь у меня есть следующие тесты, где в каждом из них я пытаюсь поиздеваться над методом "foo" несколько раз (каждый тест делает это немного по-другому):
Тест №1
@Test
public void test1() {
new MockUp<Dummy>() {
@Mock
public void foo(Invocation inv) {
System.out.println("A");
inv.proceed();
}
}
new MockUp<Dummy>() {
@Mock
public void foo(Invocation inv) {
System.out.println("B");
inv.proceed();
}
}
new Dummy().foo();
}
Тест №2
@Test
public void test2() {
mock("A");
mock("B");
new Dummy().foo();
}
private void mock(final String s) {
new MockUp<Dummy>() {
@Mock
public void foo(Invocation inv) {
System.out.println(s);
inv.proceed();
}
}
}
Единственное различие между тестами заключается в извлечении макетного кода в другой метод. Но результаты не те же самые...
Тест №1 вывод:
B
A
B
O
Это странно, потому что я бы вообще не ожидал появления А. Но в любом случае, вот результат теста №2:
B
A
A
A
...ad infinitum
Тест №2 не пройдет с StackOverflowError.
Это ошибка или я что-то упустил?
Обновление (с решением)
Как уже упоминал @Rogério, такое поведение неприемлемо.Тогда как же можно обойти МОК? любить это:
private MockUp<Dummy> mock;
@Test
public void test3() {
mockCorrectly("A");
mockCorrectly("B");
new Dummy().foo();
}
private void mockCorrectly(final String s) {
if (mock != null) {
mock.tearDown();
}
mock = new MockUp<Dummy> {
@Mock
public void foo(Invocation inv) {
System.out.println(s);
inv.proceed();
}
}
}
И для вывода:
B
O
Отлично :)
1 ответ:
Неясно, что именно здесь происходит; по-видимому, во время выполнения происходит какое-то "цепное издевательство".
Реальная проблема заключается в том, что оба теста делают что-то недопустимое с APIMockUp
: они издеваются над тем же самым методом в одном и том же классе дважды в одном и том же тесте. Это нормально иметь два разных макета для одного и того же класса в одном и том же тесте, пока они имитируют различные методы/конструкторы.Результирующее поведение не определено, так как JMockit этого не делает. поддержка нескольких одновременных издевательств над одним и тем же методом.