【发布时间】:2013-12-21 08:42:32
【问题描述】:
我已经使用这篇出色的 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()
有什么建议可以使用 MSDN 文章中的测试方法对调用 FindAsync 的方法实施单元测试:http://msdn.microsoft.com/en-US/data/dn314429#async ?
【问题讨论】:
-
您确定问题不在于您的模拟设置吗?这看起来是最复杂的部分,并且可能容易受到
NullReferenceExceptions的影响。 -
@Tim S - 你可能是对的,但它与 MSDN 文章底部用于 GetAllBlogsAsync 的模拟设置几乎相同,效果很好。
-
测试外部依赖不仅非常困难(正如您从正在创建的模拟对象的汤中看到的那样),它的价值也值得怀疑。您不仅要测试外部依赖项,还要在综合条件下对其进行测试,因为您没有调用实际的数据库,并且您的测试场景中存在很多活动部分,而这些部分在您的生活中并不存在场景(反之亦然)。
标签: c# asp.net entity-framework unit-testing moq