Подтвердить что ты не робот

Используйте Mockito для проверки того, что после метода ничего не вызывается

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

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

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

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

Обратите внимание, что я не ищу подтвержденияNoMoreInteractions: он не подтверждает, что 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");
4b9b3361

Ответ 1

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

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);

Ответ 2

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

Просто покончим с кем-то другим, который ищет здесь...

Ответ 3

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

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


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

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

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


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

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