Rhino Mocks тестирует файловую систему io - PullRequest
0 голосов
/ 05 января 2012

У меня есть приложение, которое берет словарь файлов (тип файла и список имен файлов) и копирует файлы из исходного каталога в другое место.У меня уже есть базовый код для процесса копирования, но мне нужно выполнить несколько модульных тестов, чтобы он был максимально надежным.

У меня есть класс-оболочка, который я использую, чтобы я мог проверить, что системаМетоды .IO вызываются так, как я и ожидаю, но мне трудно понять, как формировать тесты, поскольку в коде есть операторы foreach и switch.Пример кода ниже:

private IFileSystemIO _f;


public CopyFilesToDestination(IFileSystemIO f){
    _f = f;
}


public void Cpy_Files(Dictionary<string, List<string>> files)
{
// get a list of the file types in the directory
var listOfFileTypes = new List<string>(files.Keys);

foreach (var fileType in listOfFileTypes){
    var fileList = files[fileType].ToList();

    foreach  (var file in fileList){
        switch(fileType){
            case ".txt":
                _f.Copy(file, @"c:\destination\text");
                break;
            case ".dat":
                _.Copy(file, @"c:\destination\data");
                break;
        }
    }
}
}

Для проверки вышеизложенного я подумал, что буду использовать объект словаря-макета со списком типов файлов и путей:

public virtual Dictionary<string, List<string>> FakeFiles(){
    return fakeDictionary = new Dictionary<string, List<string>>(){
        {".txt",  new List<string>(){
            "c:\test\file1.txt",
                "c:\test\file2.txt"
            }
        },
        {".dat", new List<string>(){
                "c:\test\file1.dat",
                "c:\test\file2.dat"
            }
        };
    }
}

ПервыйТест, который я придумал, выглядит следующим образом:

[Test]
public void Should_Copy_Text_Files(){
    var dictionary = new FakeDictionary().FakeFiles();

    var mockObject = MockRepository.GenerateMock<IFileSystemIO>();
    var systemUnderTest = new CopyFileToDestination(mockObject);

    systemUnderTest.Cpy_Files(dictionary);

    // I think this means "test the operation, don't check the values in the arguments"      but I also think I'm wrong
    mockObject.AssertWasCalled(f => f.Copy("something", "something"), o =>     o.IgnoreArguments());

}

Моя первая проблема: Как мне проверить файл определенного типа, например, ".txt"?Тогда как мне проверить петли?Я знаю, что по поддельному словарю у меня есть только два элемента, могу ли я использовать это для формирования теста?Как?

Я думаю, что я могу быть близок к решению, но у меня заканчивается время / терпение на его поиски.Любая помощь очень ценится.Спасибо Джим

Ответы [ 2 ]

1 голос
/ 06 января 2012

Я пытался использовать решение Roberts, но, как я уже сказал, у меня слишком много разных типов файлов, чтобы настроить каждый тестовый пример отдельно. Следующим, что я попробовал, была настройка TestCaseSource, но каждый раз, когда я запускал тест, он помечал тест как проигнорированный:

[Test, TestCaseSource(typeof(FakeDictionary), "TestFiles")]
public void Cpy_Files_ShouldCopyAllFilesInDictionary(string extension, string fielName)    {
    // Arrange
    var mockObject = MockRepository.GenerateMock<IFileSystemIO>();
    var systemUnderTest = new CopyFileToDestination(mockObject);

    // Act
    systemUnderTest.Cpy_Files(dictionary);

    // Assert
    mockObject.AssertWasCalled(f => f.Copy(extension, fileName));
}

Источник данных ниже:

public static Dictionary<string, string> TestFiles{
    get
    {
        return new Dictionary<string, string>()
            {
                {".txt",
                "C:\\test\\test1.txt"},
                {".txt",
                "c:\\test\\test2.txt"}
            };
    }
} 

То, что я наконец-то разработал, использует опцию «повторить время» в Rhino и действительно довольно просто:

[Test]
public void Cpy_Files_ShouldCopyAllFilesInDictionary(){
    // Arrange
    var mockObject = MockRepository.GenerateMock<IFileSystemIO>();
    var systemUnderTest = new CopyFileToDestination(mockObject);

    // Act
    systemUnderTest.Cpy_Files(dictionary);

    // Assert

    // I know how many objects are in my fake dictionary so I set the times to repeat as a const
    const int timesToRepeat = 2;

    // now I just set the values below. I am not testing file names so the test will ignore arguments
    mockObject.AssertWasCalled(f => f.Copy("",""), options => options.Repeat.Times(timesToRepeat).IgnoreArguments());
}

Надеюсь, это поможет кому-то еще с подобной проблемой.

0 голосов
/ 05 января 2012

Я бы попробовал использовать атрибут TestCase:

[TestCase(".txt", "c:\test\file1.txt")]
[TestCase(".txt", "c:\test\file2.txt")]
[TestCase(".dat", "c:\test\file1.dat")]
[TestCase(".dat", "c:\test\file2.dat")]
public void Should_Copy_Text_Files(string extension, string fileName){
    var dictionary = new FakeDictionary().FakeFiles();
    var mockObject = MockRepository.GenerateMock<IFileSystemIO>();
    var systemUnderTest = new CopyFileToDestination(mockObject);

    systemUnderTest.Cpy_Files(dictionary);

    mockObject.AssertWasCalled(f => f.Copy(extension, fileName));
}

. Это позволит запустить тест отдельно для каждого атрибута TestCase, передав параметры, содержащиеся в нем, в метод теста.Таким образом, вы можете проверить, что каждый элемент в вашем словаре был «скопирован» без использования нескольких утверждений в одном тесте.

...