Я пытался написать модульный тест, используя jmocks и junit. (Мой проект использует ядро java - без фреймворков -) Я не мог написать модульный тест для некоторых из моих классов, издеваясь над внешними зависимостями, когда зависимости были инициализированы в конструкторе без аргументов.
Поскольку я не могу предоставить реальный код, пытаюсь объяснить сценарий на примере.
public interface Apple {
String variety();
}
Выполнение.
public class MalgovaApple implements Apple {
@Override
public String variety() {
return "Malgova";
}
}
Класс для тестирования
public class VarietyChecker {
private Apple apple;
VarietyChecker(){
this.apple = new MalgovaApple();
// instead of new, a factory method is used in actual application
}
public String printAppleVariety(){
String variety = apple.variety();
if(variety.length() < 3){
System.out.println("Donot use Code names- Use complete names");
return "bad";
}
return "good";
}
}
Тест Junit с использованием jmock
public class VarietyCheckerUnitTest{
Mockery context = new JUnit4Mockery();
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@Test
public void test_VarietyChecker() throws Exception{
final Apple mockapple = context.mock(Apple.class);
VarietyChecker printer = new VarietyChecker();
context.checking(new Expectations(){{
oneOf(mockapple).variety();will(returnValue("as"));
}});
String varietyNameValid = printer.printAppleVariety();
assertEquals("bad",varietyNameValid);
} }
Этот тест не проходит - Mocking не работает, значения "as" не вводятся, тестовый класс выполняется с помощью MalgovaApple...
Теперь, если мы добавим приведенный ниже конструктор в VarietyChecker и используем его тестовый пример, он даст ожидаемый результат...
public VarietyChecker(Apple apple) {
super();
this.apple = apple;
}
и в модульном тесте создайте объект тестового класса, например VarietyChecker.printer = new VarietyChecker(mockapple);
Выставлять новый конструктор только для целей тестирования — не лучшая идея. В конце концов, сказано, что вы не должны изменять код только для тестирования, более того, я боюсь, что мы уже написали «некоторое» (количество) кода...
Я что-то упустил в junit или jmock, что может заставить работать насмешки даже в случае конструкторов без аргументов. Или это ограничение простого junit и jmocks, и я должен перейти на что-то мощное, например Jmockit /PowerMock?