我已经使用这篇优秀的 MSDN 文章中的异步查询提供程序设置了一个测试项目:http://msdn.microsoft.com/en-US/data/dn314429#async效果很好。
然而,当我添加一个调用 FindAsync
的方法时:
public async Task<Blog> GetBlog(int blogId)
{
return await _context.Blogs.FindAsync(blogId);
}
并添加如下格式的单元测试:
[TestMethod]
public async Task GetAllBlogsAsync_gets_blog()
{
var data = new List<Blog>
{
new Blog { BlogId = 1, Name = "BBB" },
new Blog { BlogId = 2, Name = "ZZZ" },
new Blog { BlogId = 3, Name = "AAA" },
}.AsQueryable();
var mockSet = new Mock<DbSet<Blog>>();
mockSet.As<IDbAsyncEnumerable<Blog>>()
.Setup(m => m.GetAsyncEnumerator())
.Returns(new TestDbAsyncEnumerator<Blog>(data.GetEnumerator()));
mockSet.As<IQueryable<Blog>>()
.Setup(m => m.Provider)
.Returns(new TestDbAsyncQueryProvider<Blog>(data.Provider));
mockSet.As<IQueryable<Blog>>().Setup(m => m.Expression).Returns(data.Expression);
mockSet.As<IQueryable<Blog>>().Setup(m => m.ElementType).Returns(data.ElementType);
mockSet.As<IQueryable<Blog>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());
var mockContext = new Mock<BloggingContext>();
mockContext.Setup(c => c.Blogs).Returns(mockSet.Object);
var service = new BlogService(mockContext.Object);
var blog = await service.GetBlog(2);
Assert.AreEqual("ZZZ", blog.Name);
}
但是当GetBlog
从我的测试方法中调用,await _context.Blogs.FindAsync(blogId);
抛出 NullReferenceException
在TestingDemo.BlogService.<GetBlog>d__5.MoveNext()
关于如何对调用 FindAsync
的方法实现单元测试的任何建议使用 MSDN 文章中的测试方法:http://msdn.microsoft.com/en-US/data/dn314429#async ?
最佳答案
async
方法的 MoveNext
中的
NullReferenceException
几乎总是由于从另一个异步方法返回 null
.
在这种情况下,看起来 FindAsync
正在返回 null
,这是有道理的,因为我看不到您在哪里 mock 它。您目前正在模拟 IQueryable
和 GetAsyncEnumerator
方面,但不是 FindAsync
。您发布的示例文章未提供完整的 DbSet
模拟解决方案。
关于c# - 单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20382538/