NSubstitute: проверка полученных методов с аргументами массива
Я хочу проверить, что метод моего макета NSubstitute вызывается с определенным аргументом массива.
Скажем, интерфейс IProcessor
имеет метод void ProcessSomething(Foo[] something])
. Скажем, мой тестируемый класс называется Commander
. Я установил свой тест следующим образом:
//prepare
var processor = Substitute.For<IProcessor>;
var commander = new Commander(processor);
var foo1 = new Foo("alpha");
var foo2 = new Foo("bravo");
var foos = new [] {foo1, foo2};
//act
commander.DoSomething(foo1, foo2);
//verify
processor.Received().ProcessSomething(foos); // FAILS
Сбой Received()
:
NSubstitute.Exceptions.ReceivedCallsException : Expected to receive a call matching:
ProcessSomething(Foo[])
Actually received no matching calls.
Received 1 non-matching call (non-matching arguments indicated with '*' characters):
ProcessSomething(*Foo[]*)
Итак, похоже, что ProcessSomething вызывается с некоторым массивом, отличным от foos
, правильно?
Хорошо, если я вместо этого проверю это как, где я фиксирую значение аргумента с помощью Arg.Do()
, он преуспевает:
//prepare
//... as before
var actualFoos = null;
processor.ProcessSomething(Arg.Do<Foo[]>(x => actualFoos = x));
//act
commander.DoSomething(foo1, foo2);
//verify
Assert.That(actualFoos, Is.EqualTo(foos)); // SUCCEEDS
Таким образом, захват аргумента и сравнение его для равенства (с использованием NUnit в этом примере) работает, но проверка полученного вызова не выполняется.
Это ошибка в NSubstitute, или я использую ее неправильно?
Ответы
Ответ 1
Я предполагаю, что ваш объект Commander
примет аргументы и помещает их в массив, который затем использует для вызова Processor
mock.
Ваша переменная foos
- это другой массив, который вы создаете в своей настройке. Массивы не сравниваются друг с другом, даже если они имеют одинаковые элементы. Таким образом, NSubstitute будет жаловаться на то, что он не получил ожидаемого значения (он получил другой массив, в котором содержались одни и те же элементы).
Изменить: Попробуйте эту версию:
//prepare
var processor = Substitute.For<IProcessor>;
var commander = new Commander(processor);
var foo1 = new Foo("alpha");
var foo2 = new Foo("bravo");
var foos = new [] {foo1, foo2};
//act
commander.DoSomething(foo1, foo2);
//verify
processor.Received().ProcessSomething(Arg.Is<Foo[]>(foos2 => foos.SequenceEqual(foos2));
Для этого требуется импортировать пространство имен System.Linq