Mathu Mohan
Mathu Mohan

Reputation: 29

Nsubstitute mock method with any arguments is not working .net core

I'm trying to mock the method with Arg.Any<T>() parameter. The mocked method properly redirected on calling in .netframework and not in netcoreapp.

Here's a link similar to this issue , but this issue seems to be NSubstitute is not working properly in net core.

And Github Link is here

Note: Instead of passing Arg.Any value, passing the particular parameter value it works fine

Compared in both netframework(4.5.1) and net core app(2.1) libraries.

Dotnet Core result:

Test Name:  ClassLibrary1.Class1.Method
Test FullName:  ClassLibrary1.Class1.Method
Test Source:    C:\Users\mmohan\source\repos\ClassLibrary1\ClassLibrary1\Class1.cs : line 10
Test Outcome:   Failed
Test Duration:  0:00:00.177

Result StackTrace:  at ClassLibrary1.Class1.Method() in C:\Users\mmohan\source\repos\ClassLibrary1\ClassLibrary1\Class1.cs:line 16
Result Message: 
Assert.Throws() Failure
Expected: typeof(System.FormatException)
Actual:   (No exception was thrown)

Net framework result:

Test Name:  ClassLibrary1.Class1.Method
Test FullName:  ClassLibrary1.Class1.Method
Test Source:    C:\Users\mmohan\source\repos\SampleTestIssue\ClassLibrary1\Class1.cs : line 10
Test Outcome:   Passed
Test Duration:  0:00:00.292

My Code:

using NSubstitute;
using System;
using Xunit;

namespace ClassLibrary1
{
    public class Class1
    {
        [Fact]
        public void Method()
        {
            IB b = Substitute.For<IB>();
            A a = new A(b);
            b.doSomeB(Arg.Any<string>()).Returns(x => { throw new FormatException("Something there"); });
            a.doSomeA("");
            Exception exception = Assert.Throws<FormatException>(
                () => b.doSomeB(Arg.Any<string>()));
        }
    }
    public class A
    {
        public IB _b;
        public A(IB b)
        {_b = b;}
        public void doSomeA(string aa)
        {
            try
            { _b.doSomeB("");}
            catch (Exception ex){ }         
        }
    }
    public class B : IB
    {
        public string doSomeB(string bb)
        {
            try{ }
            catch (Exception ex){ }
            return "";
        }
    }
    public interface IB
    {
        string doSomeB(string bb);
    }
}

Upvotes: 2

Views: 5790

Answers (1)

tpodolak
tpodolak

Reputation: 121

The problem of inconsistent behavior is caused by wrong usage of argument matchers. In the last line of your test you do

Exception exception = Assert.Throws(
() => b.doSomeB(Arg.Any()));

so you use Arg.Any outside of NSubstitute "context" - meaning you didn't specify Returns, Throws or any other NSubstitute action which should be executed. Please take a look at documentation here and here. Long story short

Argument matchers should only be used when specifying calls for the purposes of setting return values, checking received calls, or configuring callbacks (for example: with Returns, Received or When). Using Arg.Is or Arg.Any in other situations can cause your tests to behave in unexpected ways.

When you replace Arg.Any in Assert.Throws with actual value, the test will be green.

Upvotes: 2

Related Questions