Последовательность Moq с обратным вызовом C # - PullRequest
0 голосов
/ 24 января 2019

У меня есть этот код ниже с простым тестом 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;
}
...