使用FirstOrDefaultAsync()进行Nunit测试

时间:2017-02-08 14:51:00

标签: c# unit-testing mocking async-await

我有以下方法:

public async Task<string> GetDescription(int codeId)
    {
        var Codes = Context.Codes.Where(x => x.Id == codeId).FirstOrDefault();
        return Codes.Description;
    }

以及以下单元测试:

[Test]
public async Task GetDescription()
{
    var result = await _serivce.GetSpecialtyDescription(1);
    Assert.That(result == "description");
}

我按照这样设置我的测试:

public ServicesTests()
        {
            _dbContext = new Mock<LocalContext>();

            var CodeList = new List<Codes>() { new Codes() { Id = 1, Description = "description" } };
            var dbSetCodeList = MockDbSet.GetQueryableMockDbSet(CodeList);
            _dbContext.Setup(x => x.Codes).Returns(dbSetCodeList.Object);

            _context = new DataContext<LocalContext, LocalContext>(_dbContext.Object);
            _serivce = new CodesServices(_context);
        }

public static Mock<DbSet<T>> GetQueryableMockDbSet<T>(List<T> sourceList) where T : class
        {
            var queryable = sourceList.AsQueryable();

            var dbSet = new Mock<DbSet<T>>();
            dbSet.As<IQueryable<T>>().Setup(m => m.Provider).Returns(queryable.Provider);
            dbSet.As<IQueryable<T>>().Setup(m => m.Expression).Returns(queryable.Expression);
            dbSet.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(queryable.ElementType);
            dbSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(() => queryable.GetEnumerator());
            dbSet.Setup(d => d.Add(It.IsAny<T>())).Callback<T>((s) => sourceList.Add(s));

            return dbSet;
        }

一切正常。

现在,我想等待这个功能,所以这样做:

public async Task<string> GetDescription(int codeId)
    {
        var Codes = await Context.Codes.Where(x => x.Id == codeId).FirstOrDefaultAsync();
        return Codes.Description;
    }

但是这会破坏我的单元测试 - 即使代码仍然有效。

我已经阅读了大量的文章和帖子,解释说这不起作用,因为async方法无法模拟(我认为?),但我没有遇到任何能告诉我如何解决这个问题的方法。

如果我被迫在等待我的代码或进行单元测试之间做出选择,我会感到失望,并且确定必须有办法解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

我对结果不满意,但这是迄今为止我能做的最好的事情:

public async Task<string> GetDescription(int codeId)
    {
        var Codes = await GetAll();
        return Codes.Description;
    }

        private async Task<DbSet<Codes>> GetAll()
        {
            return Context.Codes;
        }

如果有人有更好的建议,请告诉我。