سؤال

I want a unit test that verifies 2 function calls happen in the correct order. In the example, the first function encrypts a file and saves it to the file system, and the second function sends the encrypted file to a 3rd party processor (via FTP).

I am using NSubstitute as the mock framework and FluentAssertions to aid in test verification. It does not seem like this is something you can achieve with NSubstitute out of the box.

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);
}
هل كانت مفيدة؟

المحلول

Try Received.InOrder in the NSubstitute.Experimental namespace.

Something like this (I haven't tested this):

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

If you're not comfortable relying on experimental functionality, you will need to set up callbacks to store calls in order, then assert on that.

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

If you do end up trying Received.InOrder, please leave some feedback on the discussion group. If we get some feedback about it working well for others then we can promote it to the core namespace.

نصائح أخرى

Although it is not an answer persee, but verifying the explicit order as part of a unit test is bad practice. You should never test the implementation details. Just make sure the input is properly converted to the output and add some alternative scenarios that basically proof the expected behavior. That's the precise reason why this functionality was deprecated in RhinoMocks and that FakeItEasy doesn't even support it.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top