Имам структурата по-долу в мой тест, предназначен да тества дали даден журнал се извиква с правилния сложен обект на аргумент, дори когато хвърля изключение, което след това се обвива и като цяло се манипулира допълнително. LogThing има метод:
void AddEntry(LogEntry);
Така че използвам When..Do, за да хвърля изключение,
public void UnitTest()
{
// Arrange
ILogThing logThing = Substitute.For<ILogThing>()
SystemUnderTest system = new SystemUnderTest(logThing);
List<LogEntry> actualEntries = new List<LogEntry>();
LogEntry expectedEntry = GetSomeTestData();
logThing.When(
lt => lt.AddEntry(Arg.Do<LogEntry>(r => actualEntries.Add(r)))).Do(
call => { throw new InvalidOperationException("testMessage"); });
// Act
try
{
system.DoSomethingWhichLogs(someArgs)
}
catch(WrappedException ex)
{
// Assert
Assert.AreEqual(1, actualEntries.Count);
Assert.AreEqual(actualEntries[0], expectedEntry);
}
}
Очакваното извикване на Arg.Do() обаче никога не се случва с тази настройка.
Поставих точка на прекъсване в блока catch и използвах незабавния прозорец на Visual Studio, за да извикам RecievedCalls‹>() на logThing и има запис на едно извикване на logThing с правилните аргументи - просто Arg.Do изглежда, че се изпълнява само след като блокът When..Do приключи. Очевидно това означава, че тъй като хвърлям When..Do, той никога не го достига.
Наистина не очаквах NSubstitute да подреди обажданията по този начин, това очаквано поведение ли е? Ако е така, има ли нещо, което мога да направя, за да тествам входящия аргумент по този начин, или трябва просто да поставя моята проверка на аргумента в главния блок When..Do (което го прави по-труден за четене)?
Тестваната система прави различни неща спрямо изключението, което включва обгръщането й заедно с logEntry, така че е полезно за мен да имам всички тези проверки в един тест – мислех да го разделя на два отделни теста, но осъзнах че ако направя това, не мога лесно да установя откъде идва неправилният опакован изход (може да е или частта, която първоначално генерира logEntry, или частта, която го обвива), докато с този модел мога да проверя, за да се уверя logThing получава това, което очаквам. И все пак, ако има по-добър начин да направите това, със сигурност съм отворен за предложения.