У меня есть этот код ниже с простым тестом nunit с использованием Moq Sequence. Модульный тест работает без использования Callback, но не работает с Callback. Есть идеи?
public class MoqDemo
{
private ISender sender;
public MoqDemo(ISender sender)
{
this.sender = sender;
}
public void Send()
{
for (int i = 0; i < 3; i++)
{
sender.SendMessage(i, $"{i}");
}
}
}
NUnit test
[TestFixture]
public class MoqDemoTest
{
[Test]
public void SequenceTest()
{
var sender = new Mock<ISender>();
using (Sequence.Create())
{
var demo = new MoqDemo(sender.Object, repository.Object);
sender.Setup(s => s.SendTrade(2, "1")).InSequence(Times.Never());
sender.Setup(s => s.SendTrade(0, "0"))
.InSequence()
.Callback<int, string>((id, msg) =>
{
Debug.WriteLine(msg);
});
sender.Setup(s => s.SendTrade(1, "1")).InSequence();
sender.Setup(s => s.SendTrade(2, "2")).InSequence();
demo.Send();
}
}
}
Проверка не удалась в sender.Setup (s => s.SendTrade (1, "1")). InSequence ();
Сообщение об ошибке «Ожидаемый вызов на макет один раз, но было 0 раз: '' Moq.Language.Flow.VoidSetupPhrase`1 [MoqDemo.ISender] '"
Однако, если я удаляю обратный вызов, он работает
UPDATE:
Прошел исходный код Moq Sequence и обнаружил проблему с помощью этого обратного вызова и шаблона InSequence.
Внутри метод InSequence () автоматически регистрирует метод обратного вызова Moq для логики проверки последовательности. Поэтому, если я сделаю .Callback непосредственно в моем модульном тесте, он переопределит исходный обратный вызов для проверки последовательности. При запуске модульного теста, поскольку ожидаемая последовательность устанавливается на этапе настройки, а Moq.Sequence ожидает вызова ВСЕ автоматически сгенерированного обратного вызова, следовательно, модульный тест завершается неудачей.
Я расширил SequenceExtensions.cs в Moq-Sequence, и теперь он работает как положено
public static ISetup<T> InSequence<T, T1, T2>(this ISetup<T>
setup, Action<T1, T2> callback) where T : class
{
var step = Sequence.Step(setup, Times.Once());
setup.Callback<T1, T2>((id, msg) =>
{
Sequence.Record(step);
callback(id, msg);
});
return setup;
}