nsubstitute получил вызов с конкретным аргументом объекта

У меня есть класс, который выглядит примерно так:

public myArguments
{
    public List<string> argNames {get; set;}
}

В моем тесте я делаю это:

var expectedArgNames = new List<string>();
expectedArgNames.Add("test");

_mockedClass.CheckArgs(Arg.Any<myArguments>()).Returns(1);

_realClass.CheckArgs();

_mockedClass.Received().CheckArgs(Arg.Is<myArguments>(x => x.argNames.Equals(expectedArgNames));

Но тест не проходит с этим сообщением об ошибке:

NSubstitute.Exceptions.ReceivedCallsException : Expected to receive a call matching:
    CheckArgs(myArguments)
Actually received no matching calls.
Received 1 non-matching call (non-matching arguments indicated with '*' characters):
    CheckArgs(*myArguments*)

Я предполагаю, что это из-за .Equals(), но я не уверен, как это решить?


person SOfanatic    schedule 27.08.2015    source источник
comment
это хорошее решение?   -  person Cristian Lupascu    schedule 27.08.2015
comment
@ w0lf да и нет, я думаю, это сработает, но мне, вероятно, придется реализовать IEquatable, потому что List<> может быть списком других типов объектов, кроме string, спасибо   -  person SOfanatic    schedule 27.08.2015
comment
Почему вы перепутали _realClass и _mockedClass? Я не вижу кода, который вызывает CheckArgs() с переменной expectedArgNames. Не могли бы вы опубликовать воспроизводимый код   -  person Alexandr Nikitin    schedule 27.08.2015


Ответы (1)


В своем тесте вы сравниваете класс myArguments с классом List<string>.

Вы должны либо сравнить myArguments.argNames с List<string>, либо реализовать IEquatable<List<string>> в myArguments.

Кроме того, когда вы сравниваете List<T>, вы должны использовать SequenceEqualsвместо Equals.

Первый вариант будет:

_mockedClass.Received().CheckArgs(
    Arg.Is<myArguments>(x => x.argNames.SequenceEqual(expectedArgNames)));

Второй будет:

public class myArguments : IEquatable<List<string>>
{
    public List<string> argNames { get; set; }

    public bool Equals(List<string> other)
    {
        if (object.ReferenceEquals(argNames, other))
            return true;
        if (object.ReferenceEquals(argNames, null) || object.ReferenceEquals(other, null))
            return false;

        return argNames.SequenceEqual(other);
    }
}
person Marcio Rinaldi    schedule 28.08.2015
comment
Со вторым вариантом тест будет выглядеть так: x.ArgNames.Equals(expectedArgNames) правильно?, и да, я забыл включить x.argNames.Equals. - person SOfanatic; 28.08.2015
comment
Нет, со вторым вариантом у вас будет x.Equals. - person Marcio Rinaldi; 28.08.2015
comment
Для всех, кому интересно, как расширить решение первого варианта до нескольких аргументов: stackoverflow.com/a/31316858/3905007 - person youngrrrr; 24.04.2021