7

I have a class that looks something like this:

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

In my test I'm doing this:

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));

But the test fails with this error message:

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*)

I'm guessing it's because of the .Equals() but I'm not sure how to solve it?

SOfanatic
  • 5,523
  • 5
  • 36
  • 57
  • 1
    is [this](http://stackoverflow.com/a/12699199/390819) a good solution? – Cristian Lupascu Aug 27 '15 at 14:11
  • @w0lf yes and no, I think it will work but I'm probably going to have to implement `IEquatable` because the `List<>` can be a list of other object types besides `string`, thanks – SOfanatic Aug 27 '15 at 14:16
  • Why did you mix up `_realClass` and `_mockedClass`? I don't see code that calls `CheckArgs()` with `expectedArgNames` variable. Could you post **reproducible** code – Alexandr Nikitin Aug 27 '15 at 19:37

1 Answers1

8

In your test, you're comparing a myArguments class with List<string>.

You should either compare the myArguments.argNames with the List<string> or implement the IEquatable<List<string>> in myArguments.

Besides, when you are comparing List<T>, you should use the SequenceEqualsinstead of Equals.

The first option would be:

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

The second would be:

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);
    }
}
Marcio Rinaldi
  • 3,305
  • 24
  • 23
  • With the second option the test would look like this: `x.ArgNames.Equals(expectedArgNames)` right?, and yes I forgot to include the `x.argNames.Equals`. – SOfanatic Aug 28 '15 at 13:06
  • No, with the second option you'd have ```x.Equals```. – Marcio Rinaldi Aug 28 '15 at 13:58
  • For anyone curious about how to extend the first option solution to multiple arguments: https://stackoverflow.com/a/31316858/3905007 – youngrrrr Apr 23 '21 at 21:04