#java #unit-testing #dependency-injection #dependencies #automated-tests
#java #модульное тестирование #внедрение зависимостей #зависимости #автоматизированные тесты
Вопрос:
Для этого следующего класса я хочу написать модульный тест:
public class SomeClass {
private Dependency dependency;
public SomeClass(Dependency dep){
this.dependency = dep;
}
private String processString(String s){
/*
edit the string and return
*/
}
public void doSomething(String arg){
String processed = processString(arg);
dep.doSomethingElse(processed);
}
}
Сначала я бы отключил все SomeClass
вызовы методов Dependency
, чтобы протестировать мой класс изолированно.
Но вопрос, на который я пока не смог найти ответ, таков :
Должен ли я проверить, как SomeClass
вызываются методы Dependency
, например, какие параметры передаются и т.д.? Конечно, это довольно тривиальный пример, но я хочу знать, должно ли это быть частью модульного теста в целом.
Редактировать: в моем случае Dependency
это будет сторонняя библиотека api, которую я не контролирую. Поэтому я бы счел важным, какие параметры передаются этим функциям, однако я не уверен, что это должно быть частью модульного теста.
Ответ №1:
Я бы сказал, что если вызывается зависимость, то у вас должен быть хотя бы один тестовый пример, чтобы проверить, вызван ли он. Если вы не хотите рассматривать этот случай, это означает (для меня), что вам все равно не нужно его вызывать. Это очень важно, когда у вас есть какие-либо условные операторы, такие как if/else/ switch . Можете ли вы представить, что просто по ошибке вы удалили эту строку кода
dep.doSomethingElse(processed);
Не проверяя, была ли вызвана зависимость, вы даже не заметите, что удалили ее.
Тест может выглядеть так:
import static org.fest.assertions.Assertions.assertThat;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class SomeClassTest {
@Mock
private Dependency dependency;
@InjectMocks
private SomeClass someClass;
@Captor
private ArgumentCaptor<String> argumentCaptor;
@Test
public void shouldCallDependency() throws Exception {
//given
String arg = "arg";
//when
someClass.doSomething(arg);
//then
Mockito.verify(dependency).doSomethingElse(argumentCaptor.capture());
assertThat(argumentCaptor.getValue()).isEqualTo("processed");
}
}
Ответ №2:
Тестирование Dependency
не должно быть частью ваших модульных тестов класса SomeClass
, т.Е. Не проверяйте вызовы методов Dependency
на правильность и точность.
Вы можете проверить значения параметров, передаваемые методам Dependency
, если эти значения являются локальными для класса SomeClass
, т.Е. Создаются и управляются SomeClass
, в противном случае выполняя обычные утверждения проверки ввода.
Ответ №3:
Это действительно зависит от ситуации и в значительной степени зависит от мнения…
Я бы сказал, если вызовы зависимости просто помогают вашему методу выполнять свою работу, не тестируйте вызов. Просто проверьте, выполняет ли ваш метод свою работу.
Если вызов зависимости важен, например, когда вызов зависимости является важной частью функциональности или даже всей причиной выполнения вашего метода, вам следует рассмотреть возможность проверки правильности вызова зависимости.
Спросите себя: вас действительно волнует, что зависимость вызывается и вызывается правильно, или вам просто важно, чтобы ваш тестируемый метод выполнял свою работу?
Или посмотреть на это с другой точки зрения: является ли зависимость просто частью вашего класса или это независимый объект, с которым взаимодействует ваш класс?
Я знаю, это довольно двусмысленно, но я надеюсь, вы поняли идею.