尝试在.Equals上设置返回值时,CanNotSetReturnDueToNoLastCallException

时间:2015-02-26 23:03:17

标签: c# mocking nsubstitute

我使用的是最新版本的NSubstitute,我收到以下错误:

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);

这是复制错误的最小项目:

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);
    }
}

我怀疑它是因为NSubstitute无法模拟已经实现的方法,即使这些是被模拟的接口,也可能是{{1}的默认实现.Equals来自object造成了困难。

是否有其他方法可以在NSubstitute中为.Equals设置返回值?

1 个答案:

答案 0 :(得分:1)

你是正确的Object.Equals导致问题。有more info in this answer

要解决此问题,可以强制它使用IEquatable<T>.Equals,如下所示:

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

这要求被测试的代码也使用该方法而不是Object上的方法。

这种困难导致我试图避免使用NSubstitute嘲笑EqualsGetHashCodeToString。一种丑陋但有效的方法是使用您自己的equals实现IsEqualTo(A a),该实现委托给真实代码中的基础Object.Equals,但提供了一个模拟的简单位置。