如何使用作为参数给出的表达式来生成替换的返回

时间:2017-10-25 07:57:04

标签: c# unit-testing lambda nunit nsubstitute

我有一个函数可以从存储库中获取一些数据并使用它做一些事情。我想测试一下,lambda表达式是否正确,以及对存储库中的数据做了什么。因此,我不是仅通过NSubstitute为给定的lambda表达式提供特定数据,而是设置一个包含多个条目的存储库(基本上是一个列表),然后测试lambda表达式是否获得正确的数据。

所以,这是我的存储库:

public class SampleRepository : ISampleRepository
{
    public virtual IEnumerable<TEntity> Get(Expression<Func<TEntity, bool>> predicate)
    {
        return dbSet.Where(predicate);
    }
}

这就是它的用法:

var samples = repository.Get(s => s.Id == id);
// do something with those "samples"

这就是我在测试中所做的:

var repo = Substitute.For<ISampleRepository>();
var samples = new List<Sample>();
samples.Add(new Sample(1)) // insert sample with id 1
samples.Add(new Sample(2)) // insert sample with id 2
Func<Sample, bool> samplePredicate = null;
repo.Get(Arg.Do<Expression<Func<Sample, bool>>>(arg => samplePredicate = arg.Compile()));
repo.Get(Arg.Any<Expression<Func<Sample, bool>>>()).Returns(samples.Where(samplePredicate));

这给了我一个例外,说明samplePredicate

.Returns(samples.Where(samplePredicate));为空

这是有道理的,因为当时尚未调用被测单位,因此没有给出任何论据。

然而,有没有办法让这项工作?例如告诉NSubstitute不要执行列表中的.Where()

1 个答案:

答案 0 :(得分:1)

这应该在一个表达式语句中完成,同时在模拟的repo上配置期望

//Arrange
var repo = Substitute.For<ISampleRepository>();
var samples = new List<Sample>();
samples.Add(new Sample(1)) // insert sample with id 1
samples.Add(new Sample(2)) // insert sample with id 2

repo.Get(Arg.Any<Expression<Func<Sample, bool>>>())
    .Returns(arg => {
        var predicate = arg.ArgAt<Expression<Func<Mitarbeiter, bool>>>(0).Compile();
        return samples.Where(predicate);            
    });