Moq 使用对象参数验证
Posted
技术标签:
【中文标题】Moq 使用对象参数验证【英文标题】:Moq verify with object parameter 【发布时间】:2012-11-09 20:29:53 【问题描述】:我正在尝试验证作为类的参数。正在测试的代码很好。该错误正在测试中。
我试过两种方法,都失败了。
这是我的尝试:
1:
this.MockImageResizeFilter.Verify(m => m.Filter(this.UploadedFileData, new ImageFilterOptions()
Width = 256,
Height = 256,
));
这总是失败,即使作为第二个参数传递的对象具有相同的属性。第一个参数验证正常。
2:
this.MockImageResizeFilter.Setup(m => m.Filter(It.IsAny<byte[]>(), It.IsAny<ImageFilterOptions>()))
.Callback<byte[], ImageFilterOptions>((data, options) =>
Assert.AreEqual(this.UploadedFileData, data, "data");
Assert.AreEqual(filterOptions.Width, options.Width, "Width");
Assert.AreEqual(filterOptions.Height, options.Height, "Height");
);
这总是通过,即使它应该失败。回调中的 Asserts 确实失败了,但是异常没有传递给外部上下文,因此测试总是通过。
你能帮我找出我做错了什么吗?
【问题讨论】:
【参考方案1】:第一次尝试更接近你想要达到的目标。
它失败的原因是 Moq(可能)使用 Object.Equals
来测试调用该方法的 ImageFilterOptions
参数是否与您在调用 Verify
时提供的实例相同.
它们不可能是同一个实例,因为在Verify
中你创建了一个new ImageFilterOptions()
。
您可以使用 Moq 的 It.Is
语法来提供验证参数是否为预期参数的表达式,而不是以这种方式执行参数检查。
在您的情况下,您要检查参数是否为ImageFilterOptions
类型,并且Width
和Height
都设置为256
。允许您这样做的表达式是:
It.Is<ImageFilterOptions>(p => p.Width == 256 && p.Height == 256)
因此,您对Verify
的调用可能如下所示:
this.MockImageResizeFilter.Verify(m => m.Filter(
this.UploadedFileData,
It.Is<ImageFilterOptions>(p => p.Width == 256 && p.Height == 256)));
【讨论】:
我必须使用的语法是:It.Is((ImageFilterOptions p) => p.Width == 256 && p.Height == 256)
。没有通用的Is
通用版本适用于我,在 API 文档nudoq.org/#!/Packages/Moq/Moq/It/M/Is(TValue) 中 - 您使用的是过时版本的起订量吗?【参考方案2】:
Moq 的Verify
方法仅告诉您从未使用您指定的参数调用该方法,而没有解释哪个参数(或参数的哪个属性)是错误的。要获得详细信息,请使用回调将参数保存到变量中,然后对其进行断言:
ImageFilterOptions passedOptions = null;
this.MockImageResizeFilter.Setup(m => m.Filter(It.IsAny<byte[]>(), It.IsAny<ImageFilterOptions>()))
.Callback<byte[], ImageFilterOptions>((data, options) =>
passedOptions = options
);
// <exercise the mocked object>
this.MockImageResizeFilter.Verify(m => m.Filter(this.UploadedFileData, It.IsAny<ImageFilterOptions>());
Assert.AreEqual(expectedOptions.Width, passedOptions.Width, "Width");
Assert.AreEqual(expectedOptions.Height, passedOptions.Height, "Height");
// (If you wanted, you could also use the callback technique to check that
// `this.UploadedFileData` was passed in for the first parameter.)
这会准确地告诉您哪个参数/属性是错误的。
您还有机会跳过单独测试每个属性,这在处理具有许多属性的对象时非常好:
using FluentAssertions;
// ...
passedOptions.Should().BeEquivalentTo(expectedOptions);
(请注意,BeEquivalentTo 确实指出了个别属性故障。)
【讨论】:
以上是关于Moq 使用对象参数验证的主要内容,如果未能解决你的问题,请参考以下文章