Статьи

Ложный финал

предисловие

Если вы уже читали какой-то другой пост в блоге о
необычном насмешке, вы можете
пропустить прелюдию по этой ссылке .

Меня попросили собрать примеры того, как макетировать Java-конструкции, известные своими проблемами тестируемости:

Я называю эти приемы необычным издевательством. Я был обеспокоен тем, что такие примеры без какого-либо руководства могут широко использоваться партнерами по команде, не имеющими большого опыта в насмешливых рамках.

Разработчики, практикующие TDD или BDD, должны знать о проблемах тестируемости этих конструкций и стараться избегать их при разработке своих тестов и модулей. По этой причине вы, вероятно, не будете часто сталкиваться с таким необычным издевательством над проектами, использующими эти замечательные методологии программирования.

Но иногда вам приходится расширять или поддерживать устаревшую кодовую базу, которая обычно содержит классы с низкой связностью . В большинстве случаев в современном беспокойном и неспокойном мире нет времени сделать такой класс простым для модульного тестирования стандартным способом. Когда вы пытаетесь провести юнит-тестирование такого класса, вы часто понимаете, что нужен необычный издевательство.

Вот почему я решил создать и поделиться соображениями рефакторинга наряду с примерами и обходными путями для  необычного насмешки. Примерами являются использование Mockito и PowerMock mocking frameworks и среда тестирования модулей TestNG.

Макет выпускного класса

Рефакторинг соображения

Измените класс на non-final (удалите ключевое слово final) и протестируйте его стандартным способом. Эту технику я использую всегда, когда могу изменить код финального класса.

Использование PowerMock

Перед использованием этого примера, пожалуйста, внимательно подумайте, стоит ли рисковать манипулированием байт-кодом в вашем проекте. Они собраны в этом блоге . На мой взгляд, его следует использовать только в очень редких случаях, которых нельзя избежать.

Тест показывает, как макетировать финальный класс с помощью платформы PowerMock. Пример охватывает:

  1. Перемешивание метода с возвращаемым значением в финальном классе
  2. Насмешка над финальным пустым методом в финальном классе
  3. Проверка вызовов методов в конечном классе

Финальный класс:

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: