Модульное тестирование пустого метода

13

Чтобы исправить ошибку в приложении, я изменил метод с именем postLogin, добавив вызов к существующему методу с именем getShoppingCart.

Код

protected void postLogin() {
  getShoppingCart();
}

Однако я не уверен, для чего лучше всего написать модульный тест postLogin.

Подход 1

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

verify(mock).getShoppingCart();

Подход 2

Проверьте побочный эффект вызова метода, выбрав значение пользовательской корзины.

AssertNotNull(user.getShoppingCart());

Один подход лучше другого?

a_b
источник
1
что облегчает понимание теста и обеспечивает чистоту кода. Если вы не уверены в дизайне теста, это МОЖЕТ также быть признаком того, что дизайн кода отключен. Убедитесь, что вы задаете следующие вопросы: « ПОЧЕМУ добавление этого вызова метода исправляет ошибку? Это ПРАВИЛЬНЫЙ способ исправить эту ошибку?»
Калеб
8
Если у вашего getShoppingCart()метода нет побочных эффектов, вам не нужно проверять, как он называется. Если у него есть побочные эффекты, вы должны действительно изменить его имя, потому что getXXX()методы обычно должны быть идемпотентными.
Жюль
@ Джулс getNextValue? Можно утверждать, что кто-то может сказать: «Не называйте это получателем; измените имя на nextValue», но я уже видел его getNextраньше. Возможно, лучшим примером будет объект, представляющий электрон; что происходит, когда я звоню getPosition? Или хуже,getPosition(); getVelocity();
Аарон

Ответы:

18

Я обычно предпочитаю метод 2.

Почему? Потому что вы хотите postLoginизменить какое-то состояние вашей системы, но то, как она это выполняет (и какие методы она вызывает для этого внутренне), - это просто деталь реализации, в которой ваш модульный тест не должен делать никаких предположений. Так что лучше сделайте свой тест, просто проверив окончательное состояние.

Док Браун
источник
4

Я бы поменял getShoppingCart на что-то вроде initializeShoppingCart, цель метода должна быть понятна любому, кто его читает, без необходимости проверять, что делает метод, и побочные эффекты, подобные этому, могут вызывать удивительное поведение у пользователей метода.

Если getShoppingCart находится в другом классе, и он уже тестируется модулем, я бы использовал подход 1 - нет необходимости снова проверять то, что уже проверено. В этом случае мы уверены, что getShoppingCart работает правильно, и мы только хотим убедиться, что он вызывается из postLogin, поэтому, если кто-то в будущем удалит этот вызов, тест не пройдёт.

Если getShoppingCart является закрытым методом, который не может быть протестирован сам по себе, то я бы использовал подход 2, чтобы убедиться, что при вызове postLogin требуемая функциональность getShoppingCart выполняется должным образом.

Настя С
источник
1

При тестировании вызова функции (void or not), который имеет побочный эффект, наиболее полно проверить, что побочный эффект не только возникает, но и проверить, что побочный эффект (выход системы или изменение состояния) является желаемым.

hotpaw2
источник
1
Хотя это и так, стоит также учесть, что детали возникающего побочного эффекта могут быть частью внутреннего состояния какого-либо другого модуля, и что, проверив эти детали, вы связали бы свой тест не только с тем модулем, который это тестирование, но также и тот другой модуль, который может привести к хрупким испытаниям, если эти детали могут измениться. Насмешка интерфейса между модулями помогает предотвратить эту проблему.
Жюль
0

Я не буду обсуждать ваш дизайн, но в вашем случае я бы выбрал первый подход, потому что модульное тестирование предназначено для проверки того, какие методы технически выполняют независимо от их работы в области, то есть что postLoginделает ваш метод ? Технически это вызывает, getShoppingCardтак что вам нужно проверить, что на самом деле вызывает getShoppingCard, я бы также создал еще один тест для getShoppingCardпроверки того, что он делает, и если у него есть побочные эффекты, я проверим его внутри этого нового теста.

La VloZ Merrill
источник
0

У вас есть ошибка в postLogin. Итак, первое, что вы должны сделать, это создать модульный тест, который при вызове postLogin без ожидаемого набора информации «провалится».

Исходя из вышеприведенной идеи, другой альтернативой из предложенных 2 является введение информации о корзине покупок в качестве параметра. Если у вас нет правильной информации, вы бросаете непроверенное исключение. Это даст понять, что без правильных деталей ваш метод обречен.

Это потребует небольшого изменения, когда клиент, вызывающий postLogin прямо сейчас, должен также передать информацию о корзине. Для меня это все еще понятно, когда вы видите, что они связаны. Это соединение будет сделано вызывающей стороной.

Тогда вам даже не нужно тестировать getShoppingCart внутри postLogin, потому что реальным тестируемым методом является postLogin. Это тот, который имеет ошибку и единственный, который требует надлежащего исправления и проверки. С введенной зависимостью вы сможете легко протестировать ее в других условиях и подтвердить, что ошибки не выдается.

gumol
источник