Чтобы продемонстрировать это, я собираюсь переписать код из моего последнего блога (2) это тестирует мой простой AddressService . Сценарий тот же, AddressService должен загрузить свойство сайта и решить, стоит ли возвращать адрес:
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 | publicAddress findAddress(intid) {    logger.info("In Address Service with id: "+ id);    Address address = Address.INVALID_ADDRESS;    if(isAddressServiceEnabled()) {      address = addressDao.findAddress(id);      address = businessMethod(address);    }    logger.info("Leaving Address Service with id: "+ id);    returnaddress;  }  privatebooleanisAddressServiceEnabled() {    returnnewBoolean(propManager.findProperty("address.enabled"));  } | 
… кроме того, я собираюсь притвориться, что SitePropertiesManager заблокирован внутри файла JAR.
Все пункты о том, как сделать унаследованный код более тестируемым, о чем я говорил ранее, остаются в силе: вам нужно перейти к внедрению зависимостей с помощью реализации SpringFactoryBean и перестать полагаться на метод статической фабрики getInstance (). Вам также нужен способ создания заглушки, которая позволит вам изолировать ваш код от базы данных и файловой системы, которая успешно используется нашим мошенническим классом. SitePropertiesManager . В этом случае, поскольку класс заблокирован в файле JAR, вы не можете просто извлечь интерфейс, вам нужно быть немного хитрее и использовать наследование. Написание заглушки с использованием наследования довольно тривиально и занимает всего несколько строк кода, как показано ниже:
| 01 02 03 04 05 06 07 08 09 10 11 12 13 | publicclassStubSitePropertiesUsingInheritance extendsSitePropertiesManager {  privatefinalMap<String, String> propMap = newHashMap<String, String>();  publicvoidsetProperty(String key, String value) {    propMap.put(key, value);  }  @Override  publicString findProperty(String propertyName) {    returnpropMap.get(propertyName);  }} | 
Основная идея заключается в том, что теперь я могу полиморфно внедрить мой экземпляр-заглушку в мой класс AddressService, не зная, что его обманули.
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | publicclassLegacyAddressServiceUsingInheritanceTest {  privateStubAddressDao addressDao;  privateStubSitePropertiesUsingInheritance stubProperties;  privateLegacyAddressService instance;  @Before  publicvoidsetUp() {    instance = newLegacyAddressService();    stubProperties = newStubSitePropertiesUsingInheritance();    instance.setPropertiesManager(stubProperties);  }  @Test  publicvoidtestAddressSiteProperties_AddressServiceDisabled() {    /* Set up the AddressDAO Stubb for this test */    Address address = newAddress(1, "15 My Street", "My Town", "POSTCODE", "My Country");    addressDao = newStubAddressDao(address);    instance.setAddressDao(addressDao);    stubProperties.setProperty("address.enabled", "false");    Address expected = Address.INVALID_ADDRESS;    Address result = instance.findAddress(1);    assertEquals(expected, result);  }  @Test  publicvoidtestAddressSiteProperties_AddressServiceEnabled() {    /* Set up the AddressDAO Stubb for this test */    Address address = newAddress(1, "15 My Street", "My Town", "POSTCODE", "My Country");    addressDao = newStubAddressDao(address);    instance.setAddressDao(addressDao);    stubProperties.setProperty("address.enabled", "true");    Address result = instance.findAddress(1);    assertEquals(address, result);  }} | 
Вы можете спросить: почему не всегда используется наследование, и ответ заключается в том, что недостатком этого метода является то, что тестовый код тесно связан с диким классом SitePropertiesManager . В этом случае это не слишком большая проблема, и, будучи прагматичным программистом, я полагаю, что это на самом деле не имеет значения, так как иметь аккуратный, проверенный и надежный код лучше, чем иметь свободный код, но без модульных тестов.
  (1) Разработан без учета модульного тестирования. 
  (2) Исходный код доступен на GitHub по адресу: 
мерзавец: //github.com/roghughe/captaindebug.git
Ссылка: Подробнее о создании заглушек для устаревшего кода — Методы тестирования 7 от нашего партнера по JCG Роджера Хьюза в блоге Captain Debug .
Статьи по Теме :
- Методы тестирования — не писать тесты
- Неправильное использование сквозных тестов — Методы тестирования 2
- Что следует тестировать? — Методы испытаний 3
- Регулярные юнит-тесты и заглушки — Методы испытаний 4
- Модульное тестирование с использованием макетов — Методы тестирования 5
- Создание заглушек для устаревшего кода — методы тестирования 6
- Почему вы должны писать модульные тесты — методы тестирования 8
- Некоторые определения — методы тестирования 9