簡體   English   中英

單元測試服務層和實體框架6

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM