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

.Returns() with multiple return values does not work correctly the first time it's called #225

Closed
chitoiur opened this issue Mar 30, 2016 · 2 comments · Fixed by #347
Closed
Labels
bug Reported problem with NSubstitute behaviour

Comments

@chitoiur
Copy link

public interface IFoo
{
  int Read(int i);
}

[TestClass]
public class UnitTest1
{
  [TestMethod]
  public void TestMethod1()
  {
    var foo = Substitute.For<IFoo>();

    foo.Read(Arg.Is<int>(x => x == 0)).Returns(0, 1, 2);
    foo.Read(Arg.Is<int>(x => x == 1)).Returns(3, 4, 5);

    Assert.AreEqual(0, foo.Read(0));
    Assert.AreEqual(3, foo.Read(1));
    Assert.AreEqual(1, foo.Read(0));
    Assert.AreEqual(4, foo.Read(1));
    Assert.AreEqual(2, foo.Read(0));
    Assert.AreEqual(5, foo.Read(1));
  }
}

The problem is that the first Assert incorrectly fails, because the first call to Read(0) returns 1, instead of 0. I can reproduce this consistently and this is the most concise reproducer I could come up with.

@dtchepak dtchepak added the bug Reported problem with NSubstitute behaviour label Mar 31, 2016
@dtchepak
Copy link
Member

Thanks for this.

The problem is that the second stub foo.Read(Arg.Is<int>(x => x == 1)) will actually call foo.Read(0) and cause the first of 0, 1, 2 to be returned. (I think it would work correctly if the conditions where ==1 and ==2 as it would filter out the 0 case.)

You could try working around the issue by specifying the ==1 case first:

[TestMethod]
  public void TestMethod1()
  {
    var foo = Substitute.For<IFoo>();
    foo.Read(Arg.Is<int>(x => x == 1)).Returns(3, 4, 5);
    foo.Read(Arg.Is<int>(x => x == 0)).Returns(0, 1, 2);
   ...

Fix notes
There is an issue with fixing this: currently the record call route returns the configured result so we can chain calls. So fixing this would break that behaviour. One option would be to not return the configured result for value types.

@chitoiur
Copy link
Author

Thanks, confirming that the workaround is working. Specifically the workaround where I don't use x == 0, but instead start at 1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Reported problem with NSubstitute behaviour
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants