Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calling .Returns with the return value of a previously-configured substitute results in default value instead #603

Closed
joelhoward0 opened this issue Dec 24, 2019 · 4 comments

Comments

@joelhoward0
Copy link

I'm not sure how to describe the situation better than the title, but here is the test (using NUnit and Shouldly)

test2.Id.ShouldBe(test1.Id); fails because test2.Id returns null.

public class Tests
{
  [Test]
  public void Test()
  {
    var test1 = Substitute.For<TestThing>();
    test1.Id.Returns(45);

    var test2 = Substitute.For<TestThing>();
    test2.Id.Returns(test1.Id);

    test2.Id.ShouldBe(test1.Id);
  }

  public interface TestThing
  {
    int? Id { get; }
  }
}

This, however, works:

[Test]
public void Test()
{
  var test1 = Substitute.For<TestThing>();
  test1.Id.Returns(45);

  var test1Id = test1.Id;
  var test2 = Substitute.For<TestThing>();
  test2.Id.Returns(test1Id);

  test2.Id.ShouldBe(test1.Id);
}

public interface TestThing
{
 int? Id { get; }
}

It seems like this must be a simple mistake I'm making, but I can't find it. What am I doing wrong here?

@dtchepak
Copy link
Member

dtchepak commented Dec 26, 2019

Hi @joelhoward0 ,

Thanks for the great code example. This isn't really your mistake; it is an unfortunate downside to NSubstitute's syntax. The problem is that calling test1 while stubbing test2 confuses NSubstitute as to which call is being stubbed. For a detailed explanation of a similar case, see this StackOverflow answer.

To work around this, replace the stub with test2.Id.Returns(x => test1.Id);, which makes the test pass on my machine (i.e. use (x => test1.Id) lambda instead of just (test1.Id)). This will defer calling test1.Id while stubbing the property, so NSubstitute knows your just dealing with the test2 call.

Hope this helps.

@joelhoward0
Copy link
Author

I see. Thank you for the explanation and for the workaround! It's better than what I had been doing.

@tpodolak
Copy link
Member

@dtchepak is this something which should be picked up by NS4000?
Original issue nsubstitute/NSubstitute.Analyzers#12 was not describing this particular corner-case but maybe we should extend NS4000 or introduce new warning?

@dtchepak
Copy link
Member

dtchepak commented Jan 4, 2020

@tpodolak I think it would be good if it is possible to add to NS4000. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants