предисловие
Если вы уже читали какой-то другой пост в блоге о необычном насмешке, вы можете пропустить прелюдию по этой ссылке .
Меня попросили собрать воедино примеры, как макетировать Java-конструкции, хорошо известные по их проблемам с тестируемостью:
- Ложный частный метод
- Ложный финальный метод
- Макет выпускного класса
- Макет конструктора
- Макет статического метода
Я называю эти приемы необычным издевательством. Я был обеспокоен тем, что такие примеры без какого-либо руководства могут широко использоваться партнерами по команде, не имеющими большого опыта в насмешливых основах.
Разработчики, практикующие TDD или BDD, должны знать о проблемах тестируемости этих конструкций и стараться избегать их при разработке своих тестов и модулей. По этой причине вы, вероятно, не будете часто сталкиваться с таким необычным насмешкой над проектом с использованием этих замечательных методологий программирования.
Но иногда вам приходится расширять или поддерживать устаревшую кодовую базу, которая обычно содержит классы с низкой связностью . В большинстве случаев в современном беспокойном и неспокойном мире нет времени сделать такой класс простым для модульного тестирования стандартным способом. Когда вы пытаетесь провести юнит-тестирование такого класса, вы часто понимаете, что нужен необычный издевательство
Вот почему я решил создать и поделиться соображениями рефакторинга наряду с примерами и обходными путями для необычного насмешки. Примерами являются использование Mockito и PowerMock Mocking Frameworks и среда модульного тестирования TestNG.
Макет выпускного класса
Рефакторинг соображения
Измените класс на non-final (удалите ключевое слово final) и протестируйте его стандартным способом. Эту технику я использую всегда, когда могу изменить код финального класса.
Использование PowerMock
Перед использованием этого примера, пожалуйста, внимательно подумайте, стоит ли рисковать манипулированием байт-кодом в вашем проекте. Они собраны в этом блоге . На мой взгляд, его следует использовать только в очень редких случаях, которых нельзя избежать.
Тест показывает, как макетировать финальный класс с помощью платформы PowerMock. Пример охватывает:
- Перемешивание метода с возвращаемым значением в финальном классе
- Насмешка над финальным пустым методом в финальном классе
- Проверка вызовов методов в конечном классе
Финальный класс:
01
02
03
04
05
06
07
08
09
10
11
12
13
|
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 + "]" ); } } |
Тестируемый класс:
01
02
03
04
05
06
07
08
09
10
11
12
13
|
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(); } } |
Тест:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
@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); } } |
связи
Другие необычные насмешливые примеры: