Как утверждать, что заменитель получил вызов с заданным списком в качестве аргумента? - PullRequest
0 голосов
/ 27 апреля 2018

Я использую NUnit в сочетании с NSubstitute для тестирования приложения. Приложение использует платформу Caliburn.Micro MVVM. Рассмотрим следующий пример кода, для которого я хотел бы создать тест. Он использует класс агрегатора событий Caliburn Micro для публикации сообщения. Я хотел бы убедиться, что событие, опубликованное в этом коде, действительно содержит ожидаемый список целых чисел (как указано в комментарии в тестовом коде ниже).

public class ExampleEvent
{
    List<int> SampleValues { get; set; }
}

public class ExampleClass
{
    private IEventAggregator _eventAggregator;

    public ExampleClass(IEventAggregator eventAggregator)
    {
        _eventAggregator = eventAggregator
    }

    public void ExampleMethod()
    {
        var exampleArray = new List<int>{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };

        _eventAggregator.PublishOnUIThread(new ExampleEvent { SampleValues = exampleArray });
    }
}

Тест для кода выше может выглядеть следующим образом ...

[TestFixture]
public class ExampleClassTests()
{
    private ExampleClass _uut;
    private IEventAggregator _eventAggregator;

    [SetUp]
    public void SetUp()
    {
        _eventAggregator = Substitute.For<IEventAggregator>();
        _uut = new ExampleClass(_eventAggregator);
    }

    [Test]
    public void ExampleMethod_ShouldRaiseEvent()
    {
        _uut.ExampleMethod();

        // I would like to add something like the line below but errors are thrown when it is executed...
        _eventAggregator.Received().PublishOnUIThread(Arg.Is<ExampleEvent>(x => x.SampleValues.Equals( new List<int>{ 1, 2, 3, 4, 5, 6, 7, 8, 9 } )))
    }
}

Как правильно это сделать?

Ответы [ 3 ]

0 голосов
/ 28 апреля 2018

Моя проблема возникла из-за того, что я не осознавал, что массивы не будут сравниваться друг с другом, даже если они имеют одинаковые элементы. Мне удалось проверить, что агрегатор событий получил вызов метода PublishOnUIThread () с ожидаемыми аргументами следующим образом.

_eventAggregator.Received().PublishOnUIThread(Arg.Is<StageOneSamplesAvailableEvent>(message => message.Samples.SequenceEqual(new List<double> { 10, 10, 10, 0, 0, 0, 0, 0 })));
0 голосов
/ 28 апреля 2018

Поскольку NKosi указывает , будьте осторожны с методом расширения здесь.

С точки зрения утверждения в используемом списке есть несколько вариантов. Этот ответ использует SequenceEqual с Arg.Is, чтобы проверить, равны ли пункты. Или вы можете использовать пользовательское расширение . В NSubstitute также есть экспериментальный API (может быть изменен), который позволяет вам определять более сложные средства сопоставления аргументов, включая , включающий в себя существующие платформы утверждений .

Наконец, мне иногда проще всего сохранить аргумент, используемый , и утверждать, используя вашу любимую платформу модульного тестирования / утверждения. Например:

ExampleEvent eventPublished = null;
eventAggregator.Publish(Arg.Do<ExampleEvent>(x => eventPublished = x), Arg.Any<Action<System.Action>>());

//ACT
_uut.ExampleMethod();

//ASSERT
MyTestFramework.Assert.CollectionsEqual(
    new List<int>{ 1, 2, 3, 4, 5, 6, 7, 8, 9 },
    eventPublished.Samples);
0 голосов
/ 27 апреля 2018

PublishOnUIThread - это метод расширения, который вызывается для IEventAggregator.Publish.

/// <summary>
/// Publishes a message on the UI thread.
/// </summary>
/// <param name="eventAggregator">The event aggregator.</param>
/// <param name = "message">The message instance.</param>
public static void PublishOnUIThread(this IEventAggregator eventAggregator, object message) {
    eventAggregator.Publish(message, Execute.OnUIThread);
}

Таким образом, вам нужно будет смоделировать IEventAggregator.Publish, чтобы убедиться, что ваши тесты выполнены должным образом.

_eventAggregator.Received().Publish(Arg.Any<ExampleEvent>(), Arg.Any<Action<System.Action>>());
...