【问题标题】:Unit testing with MOQ & EFCore using .Find with composite primary key使用带有复合主键的 .Find 使用 MOQ 和 EFCore 进行单元测试
【发布时间】:2021-02-06 15:40:51
【问题描述】:

我正在尝试找出一种方法,以便能够使用复合主键最小化 EF Core 的“查找”功能。一位工作同事指出了一个似乎确实可行的方向,但我想知道是否有更好的解决方案?

这是我目前所拥有的。

我有一个用于创建模拟数据库集的工厂类。我正在从具有此结构的列表对象创建数据库集;

public int FK { get; set; }
public string SourceId { get; }
public string EntityName { get; set; }
public int? EntityKey { get; set; }
public string IdLong { get; set; }

主键由 FK、EntityName 和 SourceId 组成。

这就是我当前创建 DBSet 的方式

  var assocMock = EFCoreFactory.CreateMockDBSet(new List<AData> { obj1, obj2});


  // Map the associated data for the EF .Find to work
  assocMock.Setup(m => m.Find(It.Is<object[]>(mm =>
     mm[0] as int? == obj1.FK &&
     mm[1].ToString() == obj1.EntityName &&
     mm[2].ToString() == obj1.SourceId
    ))).Returns(obj1);

  assocMock.Setup(m => m.Find(It.Is<object[]>(mm =>
     mm[0] as int? == obj2.FK &&
     mm[1].ToString() == obj2.EntityName &&
     mm[2].ToString() == obj2.SourceId
    ))).Returns(obj2);

  EFCoreFactory.CreateMockSet<AData>(context, assocMock.Object);

有人可以提出更好或更通用的方法吗?

UPDATE 基于下面 Shafiq 提供的链接,这是我的最新尝试,我认为它更通用,不需要我映射每个单独的对象。有人能看出这种方法有什么缺陷吗?

  assocMock.Setup(m => m.Find(It.IsAny<object[]>()))
           .Returns<object[]>(ad => assocDataList.FirstOrDefault(d => d.FK == (int)ad[0] &&
                                                                      d.EntityName == ad[1].ToString() &&
                                                                      d.SourceId == ad[2].ToString()))

【问题讨论】:

  • 这篇文章有帮助吗? stackoverflow.com/a/40956071/1718312
  • 您可能还想考虑通过 Fluent API 添加密钥,如此处配置主密钥部分的末尾所示:docs.microsoft.com/en-us/ef/core/modeling/…
  • 内存提供程序不起作用吗?
  • 到目前为止的建议虽然很有帮助,但遗憾的是并没有完全达到我的预期目标,但谢谢。 Shafiq 提供的链接很有帮助,我已经为实体指定了复合键,但为简洁起见,在我的示例中省略了。不幸的是,rgvlee 内存提供程序不能在这种特殊情况下使用。

标签: entity-framework unit-testing entity-framework-core moq


【解决方案1】:

这实际上是我所采用的答案,对我来说非常有效,非常感谢。

assocMock.Setup(m => m.Find(It.IsAny<object[]>()))
           .Returns<object[]>(ad => assocDataList.FirstOrDefault(d => d.FK == (int)ad[0] &&
                                                                      d.EntityName == ad[1].ToString() &&
                                                                      d.SourceId == ad[2].ToString()))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-24
    • 2013-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多