使用验证来确认 Moq 模拟类中的预期参数值
我正在尝试验证是否使用预期的对象参数调用了模拟中的方法。我正在使用 Moq、nUnit,并认为 AutoFixture 的 Likeness 应该可以完成工作。 下面是我正在尝试做的事情的简化版本。
有没有办法用 AutoFixture 来做到这一点?有没有更好的方法来验证 Something
是否使用适当的参数调用?
重写 A
类中的 Equals 来比较属性值,并将 Verify
行更改为:
barMock.Verify(m => m.Something(a));
通过,但是我不想在项目中的每个类(如 A)中重写 Equals 。
namespace Test
{
using Moq;
using NUnit.Framework;
using Ploeh.SemanticComparison.Fluent;
public class A
{
public int P1 { get; set; }
}
public interface IBar
{
void Something(A a);
}
public class Foo
{
public A Data { get; private set; }
public void DoSomethingWith(IBar bar)
{
Data = new A { P1 = 1 };
bar.Something(Data);
}
}
[TestFixture]
public class AutoFixtureTest
{
[Test]
public void TestSample()
{
var foo = new Foo();
var barMock = new Mock<IBar>();
var a = new A { P1 = 1 };
var expectedA = a.AsSource().OfLikeness<A>();
foo.DoSomethingWith(barMock.Object);
expectedA.ShouldEqual(foo.Data); // passes
barMock.Verify(m => m.Something(expectedA.Value)); // fails
}
}
}
I'm trying to verify that a method within a mock is called with an expected object parameter. I'm using Moq, nUnit, and thinking that AutoFixture's Likeness should get the job done.
Below is a simplified version of what i'm trying to do.
Is there a way to do this with AutoFixture? Is there a better way to verify that Something
is called with the appropriate parameter?
Overriding Equals in the A
class to compare the property values and changing the Verify
line to:
barMock.Verify(m => m.Something(a));
passes, however I'd rather not override Equals in every class like A in my project.
namespace Test
{
using Moq;
using NUnit.Framework;
using Ploeh.SemanticComparison.Fluent;
public class A
{
public int P1 { get; set; }
}
public interface IBar
{
void Something(A a);
}
public class Foo
{
public A Data { get; private set; }
public void DoSomethingWith(IBar bar)
{
Data = new A { P1 = 1 };
bar.Something(Data);
}
}
[TestFixture]
public class AutoFixtureTest
{
[Test]
public void TestSample()
{
var foo = new Foo();
var barMock = new Mock<IBar>();
var a = new A { P1 = 1 };
var expectedA = a.AsSource().OfLikeness<A>();
foo.DoSomethingWith(barMock.Object);
expectedA.ShouldEqual(foo.Data); // passes
barMock.Verify(m => m.Something(expectedA.Value)); // fails
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在
Verify
中,Moq默认检查参数的引用相等性,因此只有当您在测试和实现中提供相同的实例(除非您覆盖了Equals
)时它才会通过。在您的情况下,
expectedA.Value
仅返回在测试中创建的new A { P1 = 1 }
,当然,它与在中创建的实例不同>DoSomethingWith
。您需要使用 Moq 的
It.Is
构造来正确测试它,而不覆盖Equals
(事实上,为此您根本不需要 Autofixture):但是如果您有多个像 P1、P2、P3... AutoFixture 这样的属性可能很有用:
因为您不需要手动为所有属性编写相等性检查。
In
Verify
Moq by default checks reference equality for arguments so it only passes when you provide the same instances (except if you've overridenEquals
) in your tests and in your implementation.In you case the
expectedA.Value
just returns thenew A { P1 = 1 }
created in the test which, of course, isn't the same instance created inDoSomethingWith
.You need to use Moq's
It.Is
construct to properly test this without overridingEquals
(in fact for this you don't need Autofixture at all):But if you have multiple properties like P1,P2,P3... AutoFixture can be useful:
Because you don't need to write out the equality checks manually for all the properties.
如果您升级到 AutoFixture 2.9.1(或更高版本),您可以在 Likeness 实例上调用 CreateProxy 方法,该方法将为目标类型发出动态代理。
生成的动态代理使用 Likeness 覆盖 Equals,这简化了语法(相当多)。
以下是原始测试方法,经过修改以使用 Likeness 代理:
请注意,它还使测试断言比接受 Any 实例更加具体。
您可以找到有关此新功能的更多详细信息 此处。
If you upgrade to AutoFixture 2.9.1 (or newer) you can call the CreateProxy method on the Likeness instance which will emit a dynamic proxy for the destination type.
The generated dynamic proxy overrides Equals using Likeness which simplifies the syntax (quite a lot).
Here is the original test method, modified to use the Likeness proxy:
Note that it also makes the test assertion much more specific than accepting Any instance.
You can find more details on this new feature here.