【问题标题】:How to Mock Entity Framework Core Change Tracking如何模拟实体框架核心变更跟踪
【发布时间】:2019-07-01 17:25:40
【问题描述】:

我有一个像这样的模拟上下文设置。

// Creates a working Fake Db Set of FakeClass Type
var fakeDbSet = Mockings.CreateDbSetMock(fakeData);  
var fakeContext = new Mock<FakeContext>();  
fakeContext.Setup(c => c.FakeData).Returns(fakeDbSet);     

访问 Context 本身和 FakeData 按预期工作。 但现在我正在尝试为访问 fakeContext 的 ChangeTracker 的函数编写单元测试。

ctx.ChangeTracker.AutoDetectChangesEnabled = false;  

现在测试失败并抛出异常,因为访问模拟上下文的 ChangeTracker 返回 null。

有没有办法模拟 Context 的 ChangeTracker?

我已经尝试使用模拟的 ChangeTracker 设置模拟的上下文,但我无法创建有效的实例,因为它在构造函数中需要上下文本身。

【问题讨论】:

    标签: c# unit-testing mocking entity-framework-core moq


    【解决方案1】:

    您需要封装 ChangeTracker 调用。它变得丑陋,但一种方法是:

    1. 修改您的生产代码以通过工厂设置上下文,以便您可以使用接口来处理上下文。
      using (var ctx = _data.Create())
    2. 扩展界​​面以包括跟踪器的切换。
      void SetChangeTracking(bool enabled);
    3. 扩展您的 FakeContext 以实现新的包装器接口。

    然后你可以在你的生产代码中调用SetChangeTracking(true);。 SetChangeTracking 实现应该修改 ctx 对象,而测试代码可以安全地返回 void。

    【讨论】:

      【解决方案2】:

      在某些情况下,模拟 EF DbContext 可能非常棘手,但在大多数情况下,您不需要(也不应该)模拟 DbContext。您可以使用 InMemoryDatabase 选项而不是模拟 DbContext。(如果您需要 DbQuery 或任何与 RDBMS 相关的功能,这将不会帮助您)

       var options = new DbContextOptionsBuilder<MyContext>().UseInMemoryDatabase(databaseName: "MyInMemoryDB").Options;
       var ctx = new MyContext(options);
      

      Read more about Testing In Memory

      但是,如果您坚持使用模拟 DbContext,请查看此线程:https://forums.asp.net/t/2155192.aspx?Mocking+EF+Core+DBContext+with+ChangeTracker

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-05-13
        • 2013-10-04
        • 2011-04-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-19
        相关资源
        最近更新 更多