[英]Unit Testing Service Layer and Entity Framework 6
我刚刚开始单元测试,所以如果这是一个明显的答案,请原谅我。
首先,我没有存储库层,因为我认为不需要对Entity Framework进行抽象,所以我有一个包含我的DbContext的项目,然后我的服务层将其称为。
我正在尝试为我的服务层构建单元测试,到目前为止有很多问题,但是几乎在那里。 到目前为止,我有这个
[TestClass]
public class PageServiceTests
{
private Mock<DbSet<Page>> _mockSet;
private Mock<IDataContext> _mockContext;
private PageService _service;
[TestInitialize]
public void TestInitialize()
{
var data = new List<Page>
{
new Page { Id = 1, Name = "Page1" },
new Page { Id = 2, Name = "Page2", IsHomePage = true },
new Page { Id = 3, Name = "Page3" }
}.AsQueryable();
_mockSet = data.MockSet<Page>();
_mockContext = new Mock<IDataContext>();
_mockContext.Setup(e => e.IsDetached(It.IsAny<Page>())).Returns(true);
_mockContext.Setup(e => e.Pages).Returns(_mockSet.Object);
_mockContext.Setup(e => e.Set<Page>()).Returns(_mockSet.Object);
_service = new PageService(_mockContext.Object);
}
[TestMethod]
public void GetAllAsync()
{
var pages = _service.GetAllAsync().Result;
Assert.AreEqual(3, pages.Count);
Assert.AreEqual("Page1", pages.ElementAt(0).Name);
Assert.AreEqual("Page2", pages.ElementAt(1).Name);
Assert.AreEqual("Page3", pages.ElementAt(2).Name);
}
[TestMethod]
public void GetHomePageAsync()
{
var page = _service.GetHomeAsync().Result;
Assert.AreEqual("Page2", page.Name);
}
[TestMethod]
public void GetAsync()
{
var page = _service.GetAsync(2).Result;
Assert.AreEqual("Page2", page.Name);
}
[TestMethod]
public void AddAsync()
{
var page = new Page
{
Name = "New Page",
IsHomePage = true,
Index = 1
};
var result = _service.AddAsync(page).Result;
_mockSet.Verify(m => m.Add(It.IsAny<Page>()), Times.Once);
_mockContext.Verify(m => m.SaveChangesAsync(), Times.Once);
}
}
现在这一切似乎都有效,但是我认为添加页面的测试应如下所示
[TestMethod]
public void AddAsync()
{
var page = new Page
{
Name = "New Page",
IsHomePage = true,
Index = 1
};
var result = _service.AddAsync(page).Result;
var pages = _service.GetAllAsync().Result;
Assert.AreEqual(4, pages.Count);
}
但是,当我这样做时,我会失败,因为页面仅包含3条记录而不包含4条记录。我想我不是在“模拟”服务中的Add方法以将页面添加到DbSet中。 您如何做到这一点,这是一种更好的方法,还是我应该采取的“方法”?
直接针对数据库进行测试是否是错误的做法? 似乎我只是为了使模拟框架与实体框架一起使用而跳了圈。
通过单元测试,您正在测试Linq to Object,而不是Linq to Entities。 有时这是一个很大的差异,如果您不查询真实的数据库,仍然会导致运行时错误。
很长一段时间,我都做过同样的事情……对模拟的DbSet测试我的存储库对我来说似乎是一个好习惯。 但现在不再。 今天,使用代码优先在运行时创建测试数据库非常容易。 当然,您需要准备一些样本数据。 但这仍然是您必须要做的(在您的情况下,设置模拟)。
我很好奇其他人会回答。
对于以Async
结尾的方法调用,由于我没有看到它或正在使用await
修饰符,因此它看起来好像不是真正在运行async
。 如果不等待而调用异步调用,则可能会在数据库中看到3个项目,因为该检查之后数据库添加记录操作可以完成。 我认为,如果您使用同步方法,或使用async / await装饰,则单元测试会正常工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.