重置Moq中的模拟验证? [英] Reset mock verification in Moq?

查看:36
本文介绍了重置Moq中的模拟验证?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如此设置:

public interface IFoo
{
    void Fizz();
}

[Test]
public void A()
{
    var foo = new Mock<IFoo>(MockBehavior.Loose);

    foo.Object.Fizz();

    foo.Verify(x => x.Fizz());

    // stuff here

    foo.Verify(x => x.Fizz(), Times.Never()); // currently this fails
}

基本上,我想在// stuff here处输入一些代码以使foo.Verify(x => x.Fizz(), Times.Never())通过.

Basically I'd like to enter some code at the // stuff here to make the foo.Verify(x => x.Fizz(), Times.Never()) pass.

由于这很可能构成了最小的起订量/单元测试滥用,所以我的理由是我可以执行以下操作:

And because this probably constitutes moq/unit testing abuse, my justification is so I can do something like this:

[Test]
public void Justification()
{
    var foo = new Mock<IFoo>(MockBehavior.Loose);
    foo.Setup(x => x.Fizz());

    var objectUnderTest = new ObjectUnderTest(foo.Object);

    objectUnderTest.DoStuffToPushIntoState1(); // this is various lines of code and setup

    foo.Verify(x => x.Fizz());

    // reset the verification here

    objectUnderTest.DoStuffToPushIntoState2(); // more lines of code

    foo.Verify(x => x.Fizz(), Times.Never());
}

基本上,我有一个状态对象,需要大量工作(包括制作各种模拟对象和其他操作)将其推入State1.然后,我想测试从State1到State2的过渡.与其复制或抽象代码,我不希望仅重复使用State1测试,而是将其推送到State2并执行我的断言-除了验证调用之外,我可以做所有这些事情.

Basically, I have a state object where a fair bit of work (both in terms of making various mock objects and other faffing around) is requires to push it into State1. Then I want to test the transition from State1 to State2. Instead of duplicating or abstracting the code I'd prefer to just re-use the State1 test, push it into State2 and perform my Asserts - all of which I can do except the verification calls.

推荐答案

我认为您无法重置这样的模拟.相反,如果您知道在转换到状态1时应调用Fizz一次,则可以像这样进行验证:

I don't think you can reset a mock like this. Instead, if you know that Fizz should be called once when transitioning to state 1, you can do your verifies like this:

objectUnderTest.DoStuffToPushIntoState1();
foo.Verify(x => x.Fizz(), Times.Once());  // or however many times you expect it to be called

objectUnderTest.DoStuffToPushIntoState2();
foo.Verify(x => x.Fizz(), Times.Once());

话虽如此,我仍将为此创建两个单独的测试.作为两个测试,可以更轻松地查看到状态1的转换是否失败,或者到状态2的转换是否失败.此外,当像这样一起测试时,如果您向状态1的转换失败,则测试方法会退出,并且您不会转换至状态2.

Having said that, I would still create two separate tests for this. As two tests, it's easier to see whether the transition into state 1 is failing, or the transition into state 2 is failing. Additionally, when tested together like this, if your transition into state 1 fails, the test method exits and your transition into state 2 doesn't get tested.

编辑

作为示例,我使用xUnit测试了以下代码:

As an example of this, I tested the following code with xUnit:

[Fact]
public void Test()
{
    var foo = new Mock<IFoo>(MockBehavior.Loose);

    foo.Object.Fizz();
    foo.Verify(x => x.Fizz(), Times.Once(), "Failed After State 1");

    // stuff here
    foo.Object.Fizz();
    foo.Verify(x => x.Fizz(), Times.Once(), "Failed after State 2"); 
}

该测试失败,并显示消息状态2之后失败".这模拟了如果将foo推入状态2的方法调用Fizz会发生的情况.如果是这样,第二个Verify将失败.

This test fails with the message, "Failed after State 2". This simulates what would happen if your method that pushes foo into State 2 calls Fizz. If it does, the second Verify will fail.

再次查看您的代码,因为您正在调用一个方法来验证它是否在模拟对象上调用了/不调用了另一方法,所以我认为您需要将CallBase设置为true,以便将基本DoStuffToPushIntoState2设置为而不是模拟的覆盖.

Looking at your code again, since you are calling one method to verify it does/does not call another method on the mock, I think you need to set CallBase to true so that the base DoStuffToPushIntoState2 is called rather than the mock's override.

这篇关于重置Moq中的模拟验证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆