繁体   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