У меня есть приведенная ниже структура в моем тесте, предназначенном для проверки того, что определенный журнал вызывается с правильным сложным объектом аргумента, даже когда он генерирует исключение, которое затем обертывается и обычно обрабатывается дальше. У 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 получает то, что я ожидаю. Тем не менее, если есть лучший способ сделать это, я, безусловно, открыт для предложений.