1

I'm using the latest version of NSubstitute, and I get the following error:

NSubstitute.Exceptions.CouldNotSetReturnDueToNoLastCallException was unhandled
HResult=-2146233088   
Message=Could not find a call to return from.

Make sure you called Returns() after calling your substitute (for example: mySub.SomeMethod().Returns(value)), and that you are not configuring other substitutes within Returns() (for example, avoid this: mySub.SomeMethod().Returns(ConfigOtherSub())).

If you substituted for a class rather than an interface, check that the call to your substitute was on a virtual/abstract member. Return values cannot be configured for non-virtual/non-abstract members.

Correct use:    mySub.SomeMethod().Returns(returnValue);

Potentially problematic use:

mySub.SomeMethod().Returns(ConfigOtherSub()); 

Instead try:    

var returnValue = ConfigOtherSub();     

mySub.SomeMethod().Returns(returnValue);

Here's a minimum project that replicates the error:

using System;
using NSubstitute;

public interface A
{
    string GetText();
}

public class Program
{
    public static void Main(string[] args)
    {
        var aMock = Substitute.For<A, IEquatable<string>>();

        aMock.Equals("foo").Returns(true);
    }
}

I suspect it's because NSubstitute cannot mock methods for which there's already an implementation, and even though these are interfaces being mocked, it's possible that the default implementation of .Equals from object is causing difficulties.

Is there some other way to set a return value for .Equals in NSubstitute?

Nick Udell
  • 2,420
  • 5
  • 44
  • 83

1 Answers1

1

You are correct that it is the Object.Equals that is causing the problem. There is more info in this answer.

To work around you can force it to use IEquatable<T>.Equals like this:

var aMock = Substitute.For<A, IEquatable<string>>();
var a = (IEquatable<string>)aMock;
a.Equals("foo").Returns(true);

That requires the code being tested to also use that method rather than the one on Object.

This kind of difficulty has led me to try to avoid mocking Equals, GetHashCode, and ToString with NSubstitute. One ugly but effective way is to use your own equals implementation IsEqualTo(A a) that delegates to the underlying Object.Equals in the real code, but provides an easy place to mock out.

Community
  • 1
  • 1
David Tchepak
  • 9,826
  • 2
  • 56
  • 68
  • I think the latter would probably mess up the public API a bit, developer expectations-wise, so for me it's either the former, which is probably acceptable, or I build a custom mock for the class in question. – Nick Udell Feb 27 '15 at 21:58