Макет класса в тестируемом классе
Как я могу издеваться с другими классами в моем классе, который находится под тестом?
Например:
Микласс.java
class MyClass {
public boolean performAnything() {
AnythingPerformerClass clazz = new AnythingPerformerClass();
return clazz.doSomething();
}
}
AnythingPerformerClass.java
class AnythingPerformerClass {
public boolean doSomething() {
//very very complex logic
return result;
}
}
И тест:
@Test
public void testPerformAnything() throws Exception {
MyClass clazz = new MyClass();
Assert.assertTrue(clazz.performAnything());
}
Могу ли я подделать AnythingPerformerClass
для исключения ненужной логики из AnythingPerformerClass
? Могу ли я переопределить метод doSomething()
для простого возврата true
или false
?
Почему я указываю Mockito, потому что он мне нужен для тестирования Android с Robolectric.
3 ответа:
Вы можете рефакторировать
MyClass
так, чтобы он использовал инъекцию зависимостей. Вместо того, чтобы создавать экземплярAnythingPerformerClass
, Вы можете передать экземпляр класса конструкторуMyClass
следующим образом:class MyClass { private final AnythingPerformerClass clazz; MyClass(AnythingPerformerClass clazz) { this.clazz = clazz; } public boolean performAnything() { return clazz.doSomething(); } }
Затем вы можете передать макет реализации в модульном тесте
@Test public void testPerformAnything() throws Exception { AnythingPerformerClass mockedPerformer = Mockito.mock(AnythingPerformerClass.class); MyClass clazz = new MyClass(mockedPerformer); ... }
Альтернативно, если ваш
AnythingPerformerClass
содержит состояние, то вы можете передатьAnythingPerformerClassBuilder
конструктору.
Как это в настоящее время (как объявление, так и создание экземпляра
AnythingPerformerClass
внутри метода, невозможно издеваться надAnythingPerformerClass
, используя только Mockito.Если возможно, переместите объявление и создание экземпляра
AnythingPerformerClass
на уровень класса: объявите переменную экземпляра типаAnythingPerformerClass
и создайте ее экземпляр конструктором.Таким образом, вы могли бы более легко ввести Макет
AnythingPerformerClass
во время теста и указать его поведение. Например:when(anythingPerformerClassMock.doSomething()).thenReturn(true);
Или проверить ошибку обработка:
when(anythingPerformerClassMock.doSomething()).thenTrow(new NullPointerException());