【问题标题】:Mock.Verify() failed - This setup was not matched?Mock.Verify() 失败 - 此设置不匹配?
【发布时间】:2019-12-19 22:23:32
【问题描述】:

我有以下测试代码。

var test = "Test";

var command = new MyCommand { V = test };

var mock = new Mock<IRepository>(); // IRepository has the method of Save()
var p = new P(test);
mock.Setup(x => x.Save(p)).Verifiable();

var sut = new C(mock.Object);
var result = await sut.M(command);

mock.Verify();

测试应该通过。但是,它因错误而失败,

信息: Moq.MockException:模拟: 由于以下原因,此模拟验证失败: IRepository x => x.Save(P): 此设置不匹配。 堆栈跟踪: 模拟验证()

sut.M() 会将字符串 X 转换为 P 类型,其值为 P(X)

【问题讨论】:

  • 尝试mock.Setup(x =&gt; x.Save(It.IsAny&lt;P&gt;())),否则它期望通过完全相同的P,我怀疑P 是否有值相等设置。
  • 我没有看到在 x.Save(p) 之外的任何地方使用了 p。 @juharr 的观点是我的意思。
  • 顺便说一句,Moq 可以验证一个方法没有被调用吗?
  • 是的,您可以执行mock.Verify(x =&gt; x.Save(It.IsAny&lt;P&gt;(), Times.Never)); 之类的操作。其他选项包括OnceAtLeastOnce,以及其他指定特定次数或可调用次数范围的选项。
  • 您还可以使用Callback 获取参数,以便测试它是否通过Ptest 值,例如mock.Setup(x =&gt; x.Save(It.IsAny&lt;P&gt;())).Callback&lt;P&gt;(p =&gt; Assert.Equal(p.Whaterver, test))

标签: c# moq xunit


【解决方案1】:

在我看来,您想验证您的模拟中的 Save 方法是否使用特定值调用,而不仅仅是一个类型。

我尝试了以下类似的方法,并相信它应该可以工作。我修改了你的例子。

var test = "Test";

var command = new MyCommand { V = test };

var mock = new Mock<IRepository>(); 
IRepository has the method of Save()
var p = new P(test);
mock.Setup(x => x.Save(It.IsAny<P>());

var sut = new C(mock.Object);
var result = await sut.M(command);

mock.Verify(x => x.Save(It.Is<P>(v => v.Value.Equals(p.Value))), Times.AtLeastOnce);

这会测试特定属性的值是否相等。

我用以下测试对此进行了测试:

var test = "Test";

var mock = new Mock<ITestRepository>(); // ITestRepository has the method of Save()
var p = new P(test);
mock.Setup(x => x.Save(It.IsAny<P>()));

mock.Object.Save(new P(test));

mock.Verify(x => x.Save(It.Is<P>(v => v.Value.Equals(p.Value))), Times.AtLeastOnce);

【讨论】:

  • 顺便说一句,我发现即使我没有打电话给.Verifiable(),它也可以工作?例如,_repositoryMock.Verify(x =&gt; x.Add(It.IsAny&lt;Restriction&gt;()), Times.Once) 没有它也可以工作。
  • 是的@ca9163d9 似乎这被认为是更好的验证方式。您可以通过阅读this question 了解更多信息。我已经编辑了我的答案以改用这种方法。
  • 在注释掉mock.Setup(x =&gt; x.Save(It.IsAny&lt;P&gt;()); 后才发现它有效。更新后的Verify(x =&gt; ...)还需要吗?
  • 我不认为设置是必要的,只要您正在测试的代码都不依赖于 Save 返回的内容或任何其他副作用。而且我认为如果您想测试使用某个值调用该方法,您应该保持更新的Verify
  • 是的,我现在使用更新版本。含义更清楚,Times 的第二个参数很有用。谢谢。
猜你喜欢
  • 2021-12-14
  • 1970-01-01
  • 1970-01-01
  • 2020-07-18
  • 2015-08-26
  • 2017-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多