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

Это странно, потому что я не ожидал, что A вообще появится. Но в любом случае, вот результат теста №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

Большой :)


person Eyal Roth    schedule 14.08.2013    source источник
comment
Удалось ли вам использовать классы MockUp верхнего уровня с @Injectable? Я не могу заставить классы MockUp верхнего уровня автоматически подключаться к моим тестовым классам, независимо от того, что я пробовал.   -  person Eric B.    schedule 30.09.2015


Ответы (1)


Непонятно, что именно здесь происходит; по-видимому, во время выполнения происходит какое-то «насмешливое приковывание».

Настоящая проблема заключается в том, что оба теста делают что-то недопустимое с MockUp API: они дважды имитируют один и тот же метод в одном и том же классе в одном и том же тесте. Можно использовать два разных мокапа для одного и того же класса в одном и том же тесте, если они имитируют разные методы/конструкторы.

Результирующее поведение не определено, поскольку JMockit не поддерживает несколько одновременных имитаций одного и того же метода.

person Rogério    schedule 14.08.2013
comment
Спасибо. Знаете ли вы способ смоделировать метод объекта и переопределить его? Я считаю эту функцию важной, потому что я определенным образом имитирую один из методов в моем классе в setUp (@Before), но затем в некоторых конкретных тестах я хочу иметь другое поведение для этого метода. - person Eyal Roth; 14.08.2013
comment
Я думаю, что нашел ответ на это. Я отредактирую вопрос с решением. - person Eyal Roth; 14.08.2013