Предположим, что я хочу написать единичный тест для проверки определенной функциональности, реализованной в рамках метода. Если бы я хотел полностью выполнить этот метод, мне пришлось бы выполнить дополнительную работу по настройке (ожидание ожиданий объектов и т. Д.). Вместо этого я использую следующий подход:
- Я настроил ожидания, которые я заинтересован в проверке, а затем сделаю протестированный метод выдающим специальный тип исключения (например, TerminateTestException).
- Далее в модульном тесте я обнаруживаю исключение и проверяю ожидания макета.Выбрасывание специального типа исключения для завершения теста на единицу измерения
Это прекрасно работает, но я не уверен, что это хорошая практика. Я не делаю этого регулярно, только в тех случаях, когда это экономит мне время и силы. Одна вещь, которая приходит на ум в качестве аргумента против использования этого, заключается в том, что бросание исключений занимает много времени, поэтому тесты выполняются медленнее, чем если бы я использовал другой подход.
EDIT:
Чтобы уточнить, я не изменяю код SUT. Что я делаю, я предоставляю макет объекта или переопределяю класс SUT, чтобы SUT завершил выполнение после того, как часть, которая мне интересна, выполнена.
private class TestCalculationService : CalculationService
{
public bool ValidateForSyncCalled;
protected override void ValidateForSyncCall()
{
ValidateForSyncCalled = true;
throw new ExceptionToTerminateTest();
}
}
[TestMethod]
public void CalculationService_Calculate_Sync_Calls_ValidateForSyncCall()
{
InitializeMocks();
TestCalculationService calculationService = new TestCalculationService();
calculationService.MessageInstanceFactory = _mockMessageInstanceFactory;
try
{
calculationService.Calculate(null);
Assert.Fail("Exception should have been thrown");
}
catch (ExceptionToTerminateTest)
{
//ok
}
Assert.IsTrue(calculationService.ValidateForSyncCalled);
}