2014-12-02 106 views
0

我刚开始单元测试,所以请原谅我,如果这是一个明显的答案。单元测试服务层和实体框架6

首先,我没有存储库层,因为我不认为需要实体框架的抽象,所以我有一个包含我的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.我想我不是“嘲笑”我的服务中的添加方法将页面添加到DbSet。你如何做到这一点,这是一个更好的方式,或者是我有什么应该做的“方式”?

直接对数据库进行测试是不好的做法吗?这似乎是我跳过箍环只是为了让嘲笑的框架与实体框架一起工作..

回答

3

随着你的单元测试,你正在测试Linq到对象,而不是Linq到实体。这有时是一个很大的差异,如果你不查询真正的数据库,仍然会导致运行时错误。

很长一段时间,我也做了同样的事情......测试我的存储库与嘲笑的DbSets对我来说似乎是一种很好的做法。但现在不行了。今天,使用代码首先在运行时创建测试数据库非常容易。当然,你需要准备一些样本数据。但是这是你必须做的(就你的情况来说,设置模拟)。

我很好奇别人会回答什么。

+1

感谢您的回复。我一直想知道为什么不直接使用“测试”数据库。我认为这个嘲弄的东西,本身就是更多的工作,再加上我想测试我的代码与数据库。我想我会采取你的建议,放弃模拟并创建一个测试sql数据库。再次感谢 – Gillardo 2014-12-02 13:09:55

0

对于以Async结尾的方法调用,它看起来并不像它真的在运行async,因为我没有看到那个或正在使用的await修饰符。如果您在不等待的情况下调用异步调用,那么您会在数据库中看到3个项目,因为数据库添加记录操作可能在检查后完成。我认为如果你使用同步方法,或者用async/await装饰,你的单元测试可以正常工作。