2013-04-18 10 views
2

Я хочу, чтобы модульный тест, который проверяет, что 2 вызова функций происходят в правильном порядке. В этом примере первая функция шифрует файл и сохраняет его в файловой системе, а вторая функция отправляет зашифрованный файл стороннему процессору (через 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); 
} 

ответ

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, пожалуйста, оставьте обратную связь на discussion group. Если мы получим отзывы о том, что он хорошо работает для других, мы можем продвигать его в основное пространство имен.

+1

Спасибо, Дэвид. Я забыл о конструкции When-Do, вот что я искал. Пространство имен NSubstitute.Experimental недоступно в пакете NuGet, как бы получить версию NSubstitute, которая включает это пространство имен? –

+0

Версия NuGet имеет это (это не отдельная DLL, просто используйте 'using NSubstitute.Experimental'). Он был введен с v1.5.0 (текущая версия v1.6.0). –

+1

Я попытался вначале использовать инструкцию using, и по какой-то причине она не была распознана. Он работает сейчас. Я оставил некоторые отзывы в дискуссионной группе. Благодаря! –

-1

Хотя это не ответ, но проверка явного порядка как части единичного теста - это плохая практика. Вы никогда не должны проверять детали реализации. Просто убедитесь, что вход правильно преобразован в вывод и добавляет некоторые альтернативные сценарии, которые в основном подтверждают ожидаемое поведение. Это точная причина, почему эта функция была устарела в RhinoMocks и что FakeItEasy даже не поддерживает ее.

+0

FakeItEasy поддерживает упорядоченные утверждения: https://github.com/FakeItEasy/FakeItEasy/wiki/Ordered-assertions. Я согласен, что следует избегать там, где это возможно, но это может быть полезно в некоторых случаях. –

+0

Книга Pragmatic Unit Testing включает в себя Time (порядок вещей), потому что это вполне допустимая спецификация, например: «Some validator нужно вызвать перед вызовом save». или, в этом случае, «Перед загрузкой необходимо вызывать шифр». Как еще вы могли бы обеспечить такую ​​спецификацию в методе, который вызывает методы void на его зависимостях? –

 Смежные вопросы

  • Нет связанных вопросов^_^