2

我想要一个单元测试来验证 2 个函数调用以正确的顺序发生。在示例中,第一个函数加密文件并将其保存到文件系统,第二个函数将加密文件发送到第 3 方处理器(通过 FTP)。

我使用 NSubstitute 作为模拟框架和 FluentAssertions 来帮助进行测试验证。使用 NSubstitute 开箱即用似乎无法实现这一点。

public void SendUploadToProcessor(Stream stream, string filename)
{
    var encryptedFilename = FilenameBuilder.BuildEncryptedFilename(filename);
    FileEncrypter.Encrypt(stream, filename, encryptedFilename);
    FileTransferProxy.SendUpload(encryptedFilename);
}

[TestMethod, TestCategory("BVT")]
public void TheEncryptedFileIsSent()
{
    var stream = new MemoryStream();
    var filename = Fixture.Create<string>();

    var encryptedFilename = Fixture.Create<string>();
    FilenameBuilder
        .BuildEncryptedFilename(Arg.Any<string>())
        .Returns(encryptedFilename);

    Sut.SendUploadToProcessor(stream, filename);

    // Something here to verify FileEncrypter.Encrypt() gets called first

    FileTransferProxy
        .Received()
        .SendUpload(encryptedFilename);
}
4

2 回答 2

3

Received.InOrder在命名空间中尝试NSubstitute.Experimental

像这样的东西(我还没有测试过):

Received.InOrder(() => {
  FileEncrypter.Encrypt(stream, filename, encryptedFilename);
  FileTransferProxy.SendUpload(encryptedFilename);
});

如果您不习惯依赖实验性功能,则需要设置回调以按顺序存储调用,然后对其进行断言。

var calls = new List<string>(); //or an enum for different calls
FileEncrypter.When(x => x.Encrypt(stream, filename, encryptedFilename))
             .Do(x => calls.Add("encrypt"));
FileTransferProxy.When(x => x.SendUpload(encryptedFilename))
                 .Do(x => calls.Add("upload"));
// Act

// Assert calls contains "encrypt","upload" in the correct order

如果您最终尝试,请在讨论组Received.InOrder中留下一些反馈。如果我们得到一些关于它对其他人运行良好的反馈,那么我们可以将它提升到核心命名空间。

于 2013-04-19T09:28:34.867 回答
0

虽然这不是一个持久的答案,但将显式顺序验证为单元测试的一部分是不好的做法。你永远不应该测试实现细节。只需确保将输入正确转换为输出并添加一些替代方案,这些方案基本上可以证明预期的行为。这就是为什么这个功能在 RhinoMocks 中被弃用并且 FakeItEasy 甚至不支持它的确切原因。

于 2013-04-22T18:52:54.660 回答