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