Используйте Mockito, чтобы убедиться, что после метода ничего не вызывается - PullRequest
45 голосов
/ 04 февраля 2009

Я использую Mockito для написания модульного теста на Java, и я хотел бы убедиться, что определенный метод является последним , вызываемым для объекта.

Я делаю что-то подобное в тестируемом коде:

row.setSomething(value);
row.setSomethingElse(anotherValue);
row.editABunchMoreStuff();
row.saveToDatabase();

В моем макете меня не волнует порядок, в котором я редактирую все в строке, но очень важно, чтобы я не пытался что-то сделать с ним после того, как я его сохранил , Есть ли хороший способ сделать это?

Обратите внимание, что я не ищу verifyNoMoreInteractions: он не подтверждает, что saveToDatabase является последней вызываемой вещью, и также завершается ошибкой, если я вызываю что-либо в строке, которую я не проверяю явно. Я хотел бы иметь возможность сказать что-то вроде:

verify(row).setSomething(value);
verify(row).setSomethingElse(anotherValue);
verifyTheLastThingCalledOn(row).saveToDatabase();

Если это поможет, я переключаюсь на Mockito из теста JMock, который сделал это:

row.expects(once()).method("saveToDatabase").id("save");
row.expects(never()).method(ANYTHING).after("save");

Ответы [ 3 ]

56 голосов
/ 05 февраля 2009

Я думаю, что это требует больше пользовательских работ.

verify(row, new LastCall()).saveToDatabase();

, а затем

public class LastCall implements VerificationMode {
    public void verify(VerificationData data) {
        List<Invocation> invocations = data.getAllInvocations();
        InvocationMatcher matcher = data.getWanted();
        Invocation invocation = invocations.get(invocations.size() - 1);
        if (!matcher.matches(invocation)) throw new MockitoException("...");
    }
}

Предыдущий ответ:

Вы правы. verifyNoMoreInteractions - это то, что вам нужно.

verify(row).setSomething(value);
verify(row).setSomethingElse(anotherValue);
verify(row).editABunchMoreStuff();
verify(row).saveToDatabase();
verifyNoMoreInteractions(row);
11 голосов
/ 27 января 2011

Не 100% по теме, но я просто искал противоположность проверки, и это был единственный релевантный результат, в итоге я оказался после Mockito.verifyZeroInteractions (макет);

Просто если кто-нибудь еще окажется здесь в поисках этого ...

0 голосов
/ 29 июня 2009

Этот вопрос заставил меня внести некоторые улучшения в API Verizations в JMockit (доступно в следующем выпуске 0.983).

Решение, которое я придумал, позволяет написать (в тестовом методе):


    new VerificationsInOrder() {{
        unverifiedInvocations();
        row.saveToDababase();
    }};

... если вы хотите убедиться, что определенный метод вызывается после всего остального. Чтобы убедиться, что это происходит за до всех других вызовов, просто переместите вызов наверх. Это фактически относится к любой последовательности последовательных вызовов.

Если в дополнение к вышеупомянутой проверке вы также хотите проверить, что некоторые другие методы вызываются в любом порядке, второй тест проверки может быть добавлен к тесту (до или после другого блока, это не имеет значения):


    new Verifications() {{
        row.setSomething(value);
        row.setSomethingElse(anotherValue);
    }};

Хотя этот синтаксис немного длинен из-за использования анонимных внутренних классов, он прост и гибок; обратите внимание, как он добавляет структуру в тест и избегает повторения вызовов методов (например, verify(...)). Это нечто большее, чем я описал здесь (сопоставители Hamcrest, количество вызовов и т. Д.), И оно не ограничивается проверкой методов экземпляра (статические методы и конструкторы можно проверять и проверять одинаково).

...