предисловие
Если вы уже читали какой-то другой пост в блоге о
необычном насмешке, вы можете
пропустить прелюдию по этой ссылке .
Меня попросили собрать примеры того, как макетировать Java-конструкции, известные своими проблемами тестируемости:
- Ложный частный метод
- Ложный финальный метод
- Макет выпускного класса
- Макет конструктора
- Макет статического метода
Я называю эти приемы необычным издевательством. Я был обеспокоен тем, что такие примеры без какого-либо руководства могут широко использоваться партнерами по команде, не имеющими большого опыта в насмешливых рамках.
Разработчики, практикующие TDD или BDD, должны знать о проблемах тестируемости этих конструкций и стараться избегать их при разработке своих тестов и модулей. По этой причине вы, вероятно, не будете часто сталкиваться с таким необычным издевательством над проектами, использующими эти замечательные методологии программирования.
Но иногда вам приходится расширять или поддерживать устаревшую кодовую базу, которая обычно содержит классы с низкой связностью . В большинстве случаев в современном беспокойном и неспокойном мире нет времени сделать такой класс простым для модульного тестирования стандартным способом. Когда вы пытаетесь провести юнит-тестирование такого класса, вы часто понимаете, что нужен необычный издевательство.
Вот почему я решил создать и поделиться соображениями рефакторинга наряду с примерами и обходными путями для необычного насмешки. Примерами являются использование Mockito и PowerMock mocking frameworks и среда тестирования модулей TestNG.
Макет выпускного класса
Рефакторинг соображения
Измените класс на non-final (удалите ключевое слово final) и протестируйте его стандартным способом. Эту технику я использую всегда, когда могу изменить код финального класса.
Использование PowerMock
Перед использованием этого примера, пожалуйста, внимательно подумайте, стоит ли рисковать манипулированием байт-кодом в вашем проекте. Они собраны в этом блоге . На мой взгляд, его следует использовать только в очень редких случаях, которых нельзя избежать.
Тест показывает, как макетировать финальный класс с помощью платформы PowerMock. Пример охватывает:
- Перемешивание метода с возвращаемым значением в финальном классе
- Насмешка над финальным пустым методом в финальном классе
- Проверка вызовов методов в конечном классе
Финальный класс:
public final class Plane {
public static final int ENGINE_ID_RIGHT = 2;
public static final int ENGINE_ID_LEFT = 1;
public boolean verifyAllSystems() {
throw new UnsupportedOperationException("Fail if not mocked!");
}
public void startEngine(int engineId) {
throw new UnsupportedOperationException(
"Fail if not mocked! [engineId=" + engineId + "]");
}
}
Тестируемый класс:
public class Pilot {
private Plane plane;
public Pilot(Plane plane) {
this.plane = plane;
}
public boolean readyForFlight() {
plane.startEngine(Plane.ENGINE_ID_LEFT);
plane.startEngine(Plane.ENGINE_ID_RIGHT);
return plane.verifyAllSystems();
}
}
Контрольная работа:
@PrepareForTest(Plane.class)
public class PilotTest extends PowerMockTestCase {
@Test
public void testReadyForFlight() {
Plane planeMock = PowerMockito.mock(Plane.class);
Pilot pilot = new Pilot(planeMock);
Mockito.when(planeMock.verifyAllSystems()).thenReturn(true);
// testing method
boolean actualStatus = pilot.readyForFlight();
Assert.assertEquals(actualStatus, true);
Mockito.verify(planeMock).startEngine(Plane.ENGINE_ID_LEFT);
Mockito.verify(planeMock).startEngine(Plane.ENGINE_ID_RIGHT);
}
}
Links
Source code can be downloaded from Github.
Other unusual mocking examples: