【发布时间】:2015-06-15 12:58:51
【问题描述】:
我刚刚开始学习单元测试和模拟。我花了一整天的时间阅读不同的教程,试图找到最好的一个来练习。我已经选择了Testing with a mocking framework (EF6 onwards),因为它使用的是 EF6(现代),以及似乎非常流行的模拟框架(Moq)。此外,它非常普通,托管在 MSDN 网络集上。必须得体,对吧?
我已经完全按照示例中的说明设置了一个项目,并且正在通过测试示例运行调试器,以确保我了解正在发生的事情。我正在进行的测试如下:
[TestClass]
public class QueryTests
{
[TestMethod]
public void GetAllBlogs_orders_by_name()
{
var data = new List<Blog>
{
new Blog { Name = "BBB" },
new Blog { Name = "ZZZ" },
new Blog { Name = "AAA" },
}.AsQueryable();
var mockSet = new Mock<DbSet<Blog>>();
mockSet.As<IQueryable<Blog>>().Setup(m => m.Provider).Returns(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);
//test code here
var blogs = service.GetAllBlogs();
Assert.AreEqual(3, blogs.Count);
Assert.AreEqual("AAA", blogs[0].Name);
Assert.AreEqual("BBB", blogs[1].Name);
Assert.AreEqual("ZZZ", blogs[2].Name);
}
}
这很简单,我相信我正在理解单元测试和模拟框架。凉爽的!我决定通过在服务实例化之后将service.AddBlog("ADO.NET Blog", "http://blogs.msdn.com/adonet");(来自前面的示例)插入到上面的TestMethod 中来执行一个实验来验证我自己。
我希望当我越过var blogs = service.GetAllBlogs(); 时,博客应该包含我的新条目,但事实并非如此。它只包含data的初始化中的3个。
这里发生了什么?该代码不应该将博客记录插入data 对象,从而在调用GetAllBlogs() 时将其拉出吗?也许我没有正确理解模拟的想法?
【问题讨论】:
-
模拟
DbSet<T>是出了名的困难。我强烈建议使用存储库模式并测试存储库,或者将存储库模式与内存数据库结合使用,您可以使用 Effort 轻松实现。在my blog 上了解更多关于后一种技术的信息。我非常不鼓励尝试模拟所有与 EF 相关的内容,因为它会将您的代码变成意大利面条。
标签: c# asp.net-mvc unit-testing moq