nsubstitute / NSubstitute

A friendly substitute for .NET mocking libraries.
https://nsubstitute.github.io
Other
2.67k stars 264 forks source link

NSubstitute seems not to recognize the parameter order correctly (string default method parameter null) #753

Open MuOuchen opened 1 year ago

MuOuchen commented 1 year ago

Describe the bug I get the following exception, the expected does not fit my argument definition:

    NSubstitute.Exceptions.ReceivedCallsException : Expected to receive exactly 1 call matching:
    WeirdMethod(any String, any String, <null>, System.Threading.CancellationToken)
Actually received no matching calls.
Received 1 non-matching call (non-matching arguments indicated with '*' characters):
    WeirdMethod("1", <null>, *"3"*, System.Threading.CancellationToken)

To Reproduce

Try this test for example:

using NSubstitute;
using NUnit.Framework;

[TestFixture]
public class TestClass
{

    public class ObjectWithWeirdMethod
    {

        public virtual string WeirdMethod(string s1, string s2 = null, string s3 = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            return "weird";
        }
    }

    public class UnderTest
    {
        private ObjectWithWeirdMethod _obj;

        public UnderTest(ObjectWithWeirdMethod obj) {
            _obj = obj;
        }

        public void test()
        {
            _obj.WeirdMethod("1", null, "3");
        }

    }

    [Test]
    public void test()
    {
        //given
        ObjectWithWeirdMethod mock = Substitute.For<ObjectWithWeirdMethod>();
        UnderTest underTest = new UnderTest(mock);

        var val = "test";
        mock.WeirdMethod(Arg.Any<string>(), null, Arg.Any<string>(), CancellationToken.None).Returns(val);

        //when
        underTest.test();

        //then
        mock.Received(1).WeirdMethod(Arg.Any<string>(), null, Arg.Any<string>(), CancellationToken.None);
    }

}

Expected behaviour The matched argument should be:

(Arg.Any<string>(), <null>, Arg.Any<string>(), System.Threading.CancellationToken)

Environment:

Ergamon commented 1 year ago

I cant really explain why, but the problem is the "null" in the expectation. Seems NSubstitute cannot figure the right Arg.Is syntax in that case.

If you replace the null with Arg.Is it works:

mock.Received(1).WeirdMethod(Arg.Any<string>(), Arg.Is<string>(v => v == null), Arg.Any<string>(), CancellationToken.None);