简体   繁体   English

验证Xunit中方法的执行顺序

[英]Verify the sequence of execution of methods in Xunit

I have to write the test case to verify the sequence of execution of chained methods.我必须编写测试用例来验证链式方法的执行顺序。 suppose I have written code as shown below假设我已经编写了如下所示的代码

 _store 
     .SetInput(input1)
     .Method1()
     .Method2()
     .Method3();

How can I write a test case to check SetInput executed first, method1 executed second, and so on?如何编写测试用例来检查首先执行的 SetInput,第二个执行的方法,等等? If someone changes the actual implementation or order of method chaining then the test case should fail.如果有人更改了方法链的实际实现或顺序,那么测试用例应该会失败。 I know that I can't mock the extension method then what is the best way to write the test case to check the sequence of execution of methods.我知道我不能模拟扩展方法,那么编写测试用例来检查方法执行顺序的最佳方法是什么。

Let's suppose that your _store implements the following interface:假设您的_store实现了以下接口:

public interface IStore
{
    IStore SetInput(string input);
    IStore Method1();
    IStore Method2();
    IStore Method3();
}

For the sake of simplicity here is class that makes use of an IStore implementation:为了简单起见,这里是使用IStore实现的类:

public class SystemUnderTest
{
    private readonly IStore _store;
    public SystemUnderTest(IStore store)
    {
        _store = store;
    }

    public void MyAction()
    {
        _store
            .SetInput("input1")
            .Method1()
            .Method2()
            .Method3();
    }
}

So, in order to make sure that the actions are executing in this particular order we can make use of the MockSequence ( ref ).因此,为了确保操作按此特定顺序执行,我们可以使用MockSequence ( ref )。 Here is a sample unit test for this:这是一个示例单元测试:

[Fact]
public void GivenAFlawlessStore_WhenICallMyAction_ThenItCallsTheMethodsOfTheStoreInAParticularOrder()
{
    //Arrange
    var storeMock = new Mock<IStore>();
    var expectedSequence = new MockSequence();
    storeMock.InSequence(expectedSequence).Setup(x => x.SetInput(It.IsAny<string>()))
        .Returns(storeMock.Object);
    storeMock.InSequence(expectedSequence).Setup(x => x.Method1())
        .Returns(storeMock.Object);
    storeMock.InSequence(expectedSequence).Setup(x => x.Method2())
        .Returns(storeMock.Object);
    storeMock.InSequence(expectedSequence).Setup(x => x.Method3())
        .Returns(storeMock.Object);

    var SUT = new SystemUnderTest(storeMock.Object);

    //Act 
    SUT.MyAction();

    //Assert
    storeMock.Verify(store => store.SetInput("input1"), Times.Once);
}

If you change the order either in the unit test or inside the MyAction method it will fail with a NullReferenceException , because it can't call the next method on a null.如果您在单元测试中或在MyAction方法中更改顺序,它将失败并返回NullReferenceException ,因为它无法在 null 上调用下一个方法。

Change the order inside the MyAction更改MyAction的顺序

public void MyAction()
{
    _store
        .SetInput("input1")
        .Method2()
        .Method1() //NullReferenceException
        .Method3();
}

Change the order of the MockSequence改变MockSequence的顺序

//Arrange
var storeMock = new Mock<IStore>();
var expectedSequence = new MockSequence();
storeMock.InSequence(expectedSequence).Setup(x => x.SetInput(It.IsAny<string>()))
    .Returns(storeMock.Object);
storeMock.InSequence(expectedSequence).Setup(x => x.Method1())
    .Returns(storeMock.Object);
storeMock.InSequence(expectedSequence).Setup(x => x.Method3())
    .Returns(storeMock.Object);
storeMock.InSequence(expectedSequence).Setup(x => x.Method2())
.Returns(storeMock.Object);

In order words your Setup calls won't have any effect in advance.换句话说,您的Setup调用不会提前产生任何影响。 When you call the SetInput from the MyAction the first setup will be executed in the sequence.当您从MyAction调用SetInput ,第一个设置将按顺序执行。 If you try to call Method2 before Method1 's Setup call then it will fail.如果你试图调用Method2之前, Method1Setup呼叫,则它会失败。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM