> 使用 NSubstitute 进行单元测试中的参数,c#,unit-testing,.net-core,mocking,nsubstitute"/>

首页 > 解决方案 > 验证表达式> 使用 NSubstitute 进行单元测试中的参数

问题描述

我正在进行单元测试,我想验证一个模拟对象是否收到了正确的谓词参数。但是,我无法使其工作。

这是代码的骨架:

public interface IRepository<T>
{
    Task<T> SingleOrDefaultAsync(Expression<Func<T, bool>> predicate);   
}

public class MyClass
{
    private readonly IRepository<Foo> _repository

    public MyClass(IRepository<Foo> repository)
    {
        _repository = repository;
    }

    public Task<bool> MyMethod(int id)
    {
        var foo = _repository.SingleOrDefaultAsync(x => x.Id == id);

        return foo != null;
    }
}

在我的测试课中,我有以下方法

public async Task MyTestMethod()
{
    var repository = Substitute.For<IRepository<Foo>>();
    repository.SingleOrDefaultAsync(x => x.Id == 123).Returns(Task.FromResult(new Foo()));

    var myClass = new MyClass(repository);

    var result = await myClass.MyMethod(123);

    result.Should().BeTrue();
}

但如上所述,这个测试失败了。我可以通过使用让它通过Arg.Any<Expression<Func<Foo, bool>>,但感觉不对。

有人建议我做错了什么吗?

标签: c#unit-testing.net-coremockingnsubstitute

解决方案


捕获传递给模拟的表达式并在 中使用它Returns来验证预期的行为。

例如

public async Task MyTestMethod() {
    //Arrange
    var id = 123;
    var model = new Foo() {
        Id = id;
    }

    var repository = Substitute.For<IRepository<Foo>>();

    repository.SingleOrDefaultAsync(Arg.Any<Expression<Func<Foo, bool>>())
        .Returns(args => {
            var expression = args.Arg<Expression<Func<Foo, bool>>(); //capture expression
            Foo result = expression.Compile()(model) ? model : null; //use to verify behavior
            Task.FromResult(result);
        });

    var myClass = new MyClass(repository);

    //Act
    var actual = await myClass.MyMethod(id);

    //Assert
    actual.Should().BeTrue();
}

推荐阅读