NSubstitute icon indicating copy to clipboard operation
NSubstitute copied to clipboard

Mocked method returning null when called from a different project

Open DavidKlempfner opened this issue 5 years ago • 1 comments

I have this test class:

using NSubstitute;
using NUnit.Framework;
using System;
using System.Linq.Expressions;

namespace MyTests
{    
    public class Tests
    {
        [Test]
        public void Test()
        {
            var companyBL = Substitute.For<ICompanyBL>();

            companyBL.GetCompany(c => new { c.RegionID }).ReturnsForAnyArgs(new
            {
                RegionID = 4,
            });

            var company = companyBL.GetCompany(c => new { c.RegionID });

            var dataRetriever = new DataRetriever(companyBL);
        }
    }
}

and this code in another project:

namespace MyTests
{
    using System;
    using System.Linq.Expressions;

    public interface ICompanyBL
    {
        T GetCompany<T>(Expression<Func<Company, T>> selector);
    }

    public partial class Company
    {
        public int RegionID { get; set; }
    }

    public class DataRetriever
    {
        public DataRetriever(ICompanyBL companyBL)
        {
            //This is null:
            var company = companyBL.GetCompany(c => new
            {
                c.RegionID
            });
        }
    }
}

The company var is null. However, when the code is all contained in the same .cs file in the same project, the value is not null.

Why is the value null when used in another file in another project?

NSubstitute version = 1.10.0.0.

.NET Framework version = 4.5.2.

StackOverflow question: https://stackoverflow.com/questions/58945013/mocked-method-returning-null-when-called-from-a-different-project

DavidKlempfner avatar Nov 21 '19 05:11 DavidKlempfner

Hello again @backwardsDave1 ! 😄

I think this answer has a good explanation: the type used for ReturnsForAll is different to the type in the production code (C# has nominal types, not structural types, so new { RegionID = 1 } is not the same as new { RegionID = 1 } defined somewhere else).

I don't think there is a way to change this behaviour with NSubstitute, as it is part of how .NET generics work.

I'll leave this issue open in case others have suggestions on how we can help this case.

dtchepak avatar Nov 21 '19 06:11 dtchepak