Я смотрел довольно современный проект, созданный с большим упором на модульное тестирование. В соответствии со старой поговоркой "каждая проблема в объектно-ориентированном программировании может быть решена путем введения нового слоя косвенности", этот проект носил несколько слоев косвенности. Побочным эффектом было то, что достоверный объем кода выглядел следующим образом:
public bool IsOverdraft)
{
balanceProvider.IsOverdraft();
}
Теперь, из-за empahsis по модульному тестированию и поддержанию высокого охвата кода, каждая часть кода имела модульные тесты, написанные против него. Поэтому этот маленький метод будет иметь три модульных теста. Они будут проверять:
- Если balanceProvider.IsOverdraft() возвращает true, то IsOverdraft должен возвращать true
- Если balanceProvider.IsOverdraft() возвращает false, то IsOverdraft должен возвращать false
- Если balanceProvider выдает исключение, то IsOverdraft должен удалить одно и то же исключение
Чтобы усугубить ситуацию, используемая система фраз (NMock2) приняла имена методов как строковые литералы, как показано ниже:
NMock2.Expect.Once.On(mockBalanceProvider)
.Method("IsOverdraft")
.Will(NMock2.Return.Value(false));
Это очевидно сделало правило "красный, зеленый, рефактор" на "красный, зеленый, рефакторинг, переименование в тесте, переименование в тесте, переименование в тесте". Использование размытых фреймов, таких как Moq, поможет в рефакторинге, но для этого потребуется прокрутка всех существующих модульных тестов.
Каков идеальный способ справиться с этой ситуацией?
A) Сохраняйте меньшие уровни слоев, чтобы эти переадресационные вызовы больше не выполнялись.
B) Не проверяйте эти методы пересылки, так как они не содержат бизнес-логики. Для целей охвата все они отмечены атрибутом ExcludeFromCodeCoverage.
C) Проверяйте только, если вызывается правильный метод, без проверки возвращаемых значений, исключений и т.д.
D) Подсуньте его и продолжайте писать эти тесты;)