Как проверить, что одно из многих условий выполнено на Мокито? Можно ли проверить, был ли вызван один ИЛИ другой метод?

1

На моем модульном тесте я хочу проверить, был ли вызван тот или иной метод. Я легко могу проверить, сколько раз некоторые методы вызываются благодаря Mockito, но у verify нет режима проверки, такого как "ИЛИ". Есть обходные пути?

В моем случае я хочу, чтобы проверить, если на SharedPreferences.Editor назывались .apply() или .commit(), потому что две из этих возможностей удовлетворяют меня и сохраняют данные. К сожалению, если я вызову verify(mEditor).apply() но кто-то изменит реализацию на .commit() в примере из-за требования мгновенного сохранения, тест не пройдёт, но не должен, потому что я хочу тестировать только с этой точки посмотреть, если данные сохранены или нет. Это модульное тестирование, которое должно быть независимым от подобных изменений и проверять только объем того, что тестируется внутри.

Теги:
junit
mockito

2 ответа

0

Обходной путь может заключаться в том, чтобы перехватить лежащую в основе MockitoAssertionError (или просто AssertionError):

try {
  verify(mEditor).apply();
} catch (MockitoAssertionError mae) {
  // apply was not called. Let verify commit instead.
  verify(mEditor).commit();
}

В качестве альтернативы, если и apply и commit вызов некоторого (внутреннего) метода save вы также можете попытаться проверить это (при условии, что оно открыто - фиктивное тестирование может противоречить скрытию информации). Или, если у вас есть контроль над кодом, который вы тестируете, вы можете реорганизовать его в соответствии с этим.

0

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

Вы знаете, что должен делать ваш производственный код. Значение: вместо написания единого фрагмента кода проверки, который позволяет "то или это", лучше написать два независимых теста, один для "этого" и один для "этого".

Другими словами: вы контролируете то, что входит в ваши тесты. Поэтому напишите один тест, который должен привести к apply(), и один, который должен привести к commit(). И затем verify() что один случай, который должен увидеть каждый тест!

Юнит тесты должны быть прямыми. Когда что-то не получается, вы быстро просматриваете unit тест и уже знаете, где искать производственный код, чтобы определить причину. Все, что добавляет сложности вашим тестам, может усложнить задачу. Лучше иметь два теста, которые следуют четкому пути "когда проверять", вместо того, чтобы иметь один (или несколько) тестов, которые идут "когда проверяют это ИЛИ проверяют это".

  • 0
    Хорошо, у вас есть хорошие предложения, но если я напишу два отдельных теста - один из которых должен привести к apply() а другой в commit() , один из них всегда будет неудачным, верно? Или вы имеете в виду только сосредоточиться на том, что я должен знать, как это реализовано в рабочем коде? Проблема в том, что оба эти метода выполняют то, что я (и мой модульный тест) ожидаем, оба сохраняют данные. Один делает это асинхронным способом, а второй делает это немедленно, и оба способа здесь приемлемы. Может быть, я ошибаюсь, но когда я смотрю и думаю с точки зрения теста, я задаюсь вопросом, что является минимальным для удовлетворения требований из названия теста.
  • 0
    @ user3054470 Конечно, здесь размытая линия. Но как сказано: отдельные тесты должны проверять один конкретный путь. И этот путь должен быть четко виден читателю этого теста. Видите ли, по крайней мере, когда речь идет о модульном тесте, это имеет большое значение, если вы ожидаете, что вызывается apply () или вызывается commit (). Так почему бы не пройти тесты, и каждый из них идет к определенной цели? Это может быть иначе для функционального / интеграционного теста.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню