【问题标题】:Mock result from Func with NSubstitute使用 NSubstitute 的 Func 模拟结果
【发布时间】:2015-10-08 13:38:50
【问题描述】:

我正在尝试使用 NSubstitute 来模拟来自 Substitute 的返回值,但由于方法签名使用的是 Func,因此我无法让替代品返回正确的值。

我已经看到了这些问题,但无法使其与我的 Func 一起使用。

Mocking Action<T> with NSubstitute

Mocking out expression with NSubstitute

我尝试模拟的界面是这样的(有点简单):

public interface IOrgTreeRepository<out T> where T : IHierarchicalUnit
{
    T FirstOrDefault(Func<T, bool> predicate);
}

我用 NSubstitute 代替它,如下所示:

_orgTreeRepository = Substitute.For<IOrgTreeRepository<IOrganizationUnit>>();

然后我尝试像这样更改返回值:

_orgTreeRepository.FirstOrDefault(Arg.Is<Func<IOrganizationUnit, bool>>(x => x.Id== _itemsToUpdate[0].Id)).Returns(existingItems[0]);

但它只是返回一个代理对象而不是我在 existingItems 中定义的对象。

但是,多亏了其他问题,我设法让它工作,但这对我没有帮助,因为我每次都需要一个特定的项目。

_orgTreeRepository.FirstOrDefault(Arg.Any<Func<IOrganizationUnit, bool>>()).Returns(existingItems[0]); // Semi-working

我猜它会将 lambda 表达式视为一种绝对引用,因此会跳过它?有什么方法可以模拟返回值吗?

【问题讨论】:

    标签: c# unit-testing nsubstitute


    【解决方案1】:

    正如您猜对的那样,NSubstitute 在这里只使用引用相等,所以除非您引用相同的谓词(有时这是一个选项),否则您必须匹配任何调用(Arg.Any.ReturnsForAnyArgs)或者使用近似形式的匹配来检查传入的函数。

    近似匹配示例:

    [Test]
    public void Foo() {
        var sample = new Record("abc");
        var sub = Substitute.For<IOrgTreeRepository<Record>>();
        sub.FirstOrDefault(Arg.Is<Func<Record,bool>>(f => f(sample))).Returns(sample);
    
        Assert.AreSame(sample, sub.FirstOrDefault(x => x.Id.StartsWith ("a")));
        Assert.AreSame(sample, sub.FirstOrDefault(x => x.Id == "abc"));
        Assert.Null(sub.FirstOrDefault(x => x.Id == "def"));
    }
    

    在这里,每当Func&lt;T,bool&gt;sample 返回true 时,我们将FirstOrDefault 存根返回sample(这是使用Arg.Is 的不同重载,它采用表达式,而不是值传入的参数)。

    这通过了两个不同谓词的测试,因为sample 满足这两个谓词。它还通过了最后一个断言,因为它不会为检查不同 id 的函数返回 sample。我们不能保证在这种情况下使用了特定的谓词,但这可能就足够了。否则我们会被 Func 的参考质量困住。

    希望这会有所帮助。

    【讨论】:

    • 嗯,这很好地解决了我的问题。非常感谢。
    • 我永远不会猜到!非常感谢。
    猜你喜欢
    • 2016-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多