表达式导致模拟存储库返回null

时间:2014-06-12 17:55:03

标签: c# unit-testing mocking nsubstitute

我正在尝试测试服务方法,但为了做到这一点,我必须模拟我的ReportRepository。除了调用Include方法使mock返回null之外,一切正常。

以下内容返回预期报告:

var report = new Report();
var reportRepoMock = Substitute.For<IReportRepository>();
reportRepoMock.Query()
    .ByReportType(ReportType.DELQ)
    .ToEntityAsync()
    .Returns(Task.FromResult(report));

但该服务实际上做了以下事情:

var report = await reportRepo.Query()
    .ByReportType(ReportType.DELQ)
    .Include(m => m.Fields)
    .ToEntityAsync();

问题是当我在模拟中包含'Include'方法时,返回null而不是预期的报告,所以我的测试中断了NullReferenceException

var reportRepoMock = Substitue.For<IReportRepository>();
reportRepoMock.Query()
    .ByReportType(ReportType.DELQ)
    .Include(m => m.Fields)
    .ToEntityAsync()
    .Returns(Task.FromResult(report));

那么如何在我的模拟中包含'Include'方法?

我正在尝试使用流畅的存储库,因此它们的设置有点不同。下面的很多代码都发生在抽象的泛型类中,但是我将其删除以保持问题的长度。

public class ReportRepository : IReportRepository
{
    private readonly IDbSet _dbSet;

    public ReportRepository(IDbContext context) {
        _dbSet = context.Set<Report>();
    }

    void Add(Report report) { ... }
    void Remove(Report report) { ... }
    ...

    public IReportQueryBuilder Query() {
        return new ReportQueryBuilder(_dbSet.AsQueryable());
    }
}

public class ReportQueryBuilder : IReportQueryBuilder
{
    private IQueryable<Report> _query;

    public ReportQueryBuilder(IQueryable<Report> query) {
        _query = query;
    }

    public IReportQueryBuilder ByReportType(ReportType reportType) {
        _query = _query.Where(m => m.ReportType == reportType);

        return this;
    }

    public IReportQueryBuilder Include<T>(Expression<Func<Report, T>> property) {
        _query = _query.Include(property);

        return this;
    }

    public async Task<Report> ToEntityAsync() {
        return await _query.FirstOrDefaultAsync();
    }
}

1 个答案:

答案 0 :(得分:0)

想出这个。而不是将模拟设置为:

 reportRepoMock.Query()
    .ByReportType(ReportType.DELQ)
    .Include(m => m.Fields)
    .ToEntityAsync()
    .Returns(Task.FromResult(report));

我去了:

reportRepoMock.Query()
    .ByReportType(ReportType.DELQ)
    .Include(Arg.Any<Expression<Func<Report, Collection<ReportField>>>>())
    .ToEntityAsync()
    .Returns(Task.FromResult(report));