【问题标题】:How to mock a record getting added to the DbContext如何模拟添加到 DbContext 的记录
【发布时间】:2016-06-16 18:00:02
【问题描述】:

我有这样的方法:

private void CreateTaskFromModel(ForgotPasswordViewModel fpModel)
{
    var message = _dbContext.Create<Message>();

    message.MessageType = "TASK".PadLeft(10);
    message.Assigned_User_K = fpModel.SendPasswordRequestTo.Trim();
    message.Assigned_Date = DateTime.Today;
    message.Source_User_K = string.Empty;
    message.Title_Focus = "Request Web Password";

    _dbContext.Messages.Add(message);
}

所以我能够像这样模拟Create 方法:

Message msg = new Message();
IMyDbContext fakeDbContext = NSubstitute.Substitute.For<IMyDbContext>();

fakeDbContext.Create<Message>().Returns(msg);

但请注意最后一行它仍然有这段代码,我不知道如何模拟这个?

_dbContext.Messages.Add(message);

我正在使用NSubstittue

【问题讨论】:

  • 如果您只使用 DbContext,您可以使用Testing with your own test doubles (EF6 onwards) 中概述的这个框架来实现模拟(使用 NSubstitute)。我围绕它创建了一个包装器并将其发布到GitHub,以使其更易于使用/调用。同样,为此只需注入 DbContext 而不是您实现的派生类型,然后使用通用 Set&lt;T&gt; 方法在上下文中调用您的模型。
  • @Igor 当它到达 _dbContext.Messages.Add(message);它崩溃了,因为 .Messages 为空……你能帮忙吗?
  • 您已经嘲笑了IMyDbContext ,但您还没有嘲笑它应该为IMyDbContext.Messages 返回的内容,因此它为空。您还必须模拟 Add 方法。
  • @Nkosi 是的,我知道。这就是我不知道如何编写它并提出问题的语法和部分。你能告诉我如何做那部分吗?我尽可能地嘲笑它。
  • 你是 CodeFirst 还是 DatabaseFirst ?如果您是 DatabaseFirst,则可以创建一个实例化 MetadataWorkspace 对象的模拟上下文,即 edmx 的反序列化版本。您应该能够在 SaveChanges() 方法中使用反射解析元数据并处理标识键和 FixUp 操作。 EF7 将实施 In-Memory 存储库。对于以前的版本,最困难的部分是模拟 FixUp。就我而言,它给出了很好的结果。但这是 3 天的工作。

标签: c# entity-framework unit-testing nsubstitute


【解决方案1】:

消息的类型为DbSet&lt;Message&gt;。所以你需要创建一个DbSet&lt;Message&gt; 的假/替代实例,并让_dbContext.Messages 返回我。

Message msg = new Message();
IMyDbContext fakeDbContext = NSubstitute.Substitute.For<IMyDbContext>();

var messagesSet = NSubstitute.Substitute.For<DbSet<Message>>();
fakeDbContext.Create<Message>().Returns(msg);
fakeDbContext.Messages.Returns(messagesSet);

您还想查看是否调用了 Add。您可以在 Asserts 中执行此操作。

messagesSet.Received().Add(NSubstitute.Any<Message>());

或者如果您想测试是否从您的创建中添加了相同的实例

messagesSet.Received().Add(msg); // message created earlier in your test

【讨论】:

  • 我还需要“模拟”“添加”方法吗?在 Messages.Add 中?你能告诉我怎么做吗?
  • @KSNoob - 不,你没有。除非它返回一些你可以在你的代码中重用的东西,比如 Create ,否则没有理由去模拟它。使用 NSubstitute,您可以使用上述代码查看是否调用了 Add,因为这是您感兴趣的内容。
  • 非常感谢您的帮助。我卡住了 。 :)
  • 添加的实体是用 Identity 属性设置的,你如何模拟它?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多