2014-12-02 109 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裝飾,你的單元測試可以正常工作。