【问题标题】:Moq logger & verifying calls fails最小起订量记录器和验证呼叫失败
【发布时间】:2018-03-22 17:43:04
【问题描述】:

我为我的记录器创建了一个模拟项目,以便我可以验证对其进行了哪些调用;像这样:

  mock_log.Setup(l => l.InfoFormat(It.IsAny<string>(), It.IsAny<object[]>()));
  mock_log.Verify(m => m.InfoFormat("1 file(s) found that match criteria."), Times.Exactly(1));

我已经调试了代码,并且我知道这些日志在代码中被击中,因此应该记录这些日志。这是记录该消息的代码

  _log.InfoFormat("{0} file(s) found that match criteria.", files.Count);

只有 1 个文件被传下来。

那么为什么当我验证一个呼叫时它会失败? 任何建议。

【问题讨论】:

  • 如果删除设置调用会发生什么?我认为您将 Moq 设置为期望 2 个调用 - 设置和验证。我更喜欢使用 Setup 进行准确调用,并使用 moq.VerifyAll() 来检查 Setups 是否已被使用
  • 无需调用设置,因为您正在验证您感兴趣的调用。有些人将设置与 VerifyAll 一起使用,但根据我的经验,我同意 RussellAllen 的这种方法makes it hard to tell what is being asserted

标签: c# unit-testing mocking moq verify


【解决方案1】:

发现这是因为字符串封装没有通过。将验证更改为

 mock_log.Verify(m => m.InfoFormat("{0} file(s) found on Ftp server.", 4), Times.Exactly(1));

【讨论】:

  • 如您所见,您必须验证所拨打电话的确切签名。请记住,模拟框架不知道您正在模拟的方法会等同于字符串格式。它所知道的只是使用某些参数调用了特定的方法签名。如果您的被测代码使用扩展方法,这可能会变得很棘手,因为您必须验证所进行的实际调用。
【解决方案2】:

在模拟设置中,您告诉记录器第二个参数是一个数组,但随后您在运行时传入了一个计数。我怀疑这将是问题所在。尝试更改为:

It.IsAny&lt;object&gt;()

另一个想法,您在 .Verify 中应用的测试看起来有点奇怪。我不确定 Times.Exactly(1) 是什么意思,如果模拟试图运行验证生成的格式字符串,你可能只想传入 1?

【讨论】:

  • 可能是params object[]参数,所以是一个数组。
  • 是的,它是一个参数对象[],所以设置是正确的。结果证明它是调用的确切表示,而不是外推版本。
  • 只是提醒大家不要随意使用It.IsAny。在 this question 上讨论了它在 cmets 中的使用和答案,OP 认为这很有帮助。还有提示您可以使用Times.Once 而不是Times.Exactly(1)
猜你喜欢
  • 1970-01-01
  • 2012-08-09
  • 2013-11-26
  • 1970-01-01
  • 2011-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多