Как провести модульное тестирование файлового менеджера класса? - PullRequest
1 голос
/ 27 февраля 2011

Я написал простой класс для управления бизнес-объектами.

class Manager
{ 
 string[] GetNames();
 BObject GetObject(string name);
 void Saveobject(BObject obj);
}

Он сериализует / десериализует объекты в виде файлов на локальном диске.Я написал модульные тесты для класса и запустил их.Это было хорошо до сих пор.Проблема возникает, когда мой тест был запущен на сервере сборки из-за разрешения доступа к файлам, мне не разрешалось записывать файлы на сервер.Очевидно, что я не могу проверить таким образом.

Я думаю, как это проверить модулем.Один из подходов, который я вижу, - это извлечь интерфейс и создать фиктивный объект для тестирования.Но я хочу проверить сам класс.Как я могу это сделать?

Ответы [ 2 ]

5 голосов
/ 27 февраля 2011

Класс предположительно вызывает операции файловой системы File.OpenRead(), File.OpenWrite() и т. Д. (Я предполагаю, что это C # из-за верблюжьего корпуса.) Затем вы можете создать интерфейс для этих операций, например:

public interface IFileSystem {
    StreamReader OpenRead(string fileName);
    StreamWriter OpenWrite(string fileName);
}

и заставить конструктор Manager взять экземпляр IFileSystem.Затем напишите (не фиктивный) класс, который реализует IFileSystem, вызывая фактические методы File.OpenRead() и File.OpenWrite(), и используйте этот класс в рабочем коде.В тестах вы используете фиктивный фреймворк, как упомянул @Digger (мое личное предпочтение - Moq , но я не пробовал Rhino Mocks, поэтому мне нечего сказать по этому поводу), чтобы макетироватьIFileSystem и используйте макет, чтобы проверить, что методы были вызваны с правильными сериализованными данными.

РЕДАКТИРОВАТЬ: По запросу, пример в NUnit с Moq (у меня нет IDE здесь, поэтому он не проверен; не стесняйтесь исправлять это):

[Test]
public void BObjectShouldBeSerializedToFile() {
    var fileSystemMock = new Mock<IFileSystem>();
    var stream = new MemoryStream();
    fileSystemMock.Setup(f => f.OpenWrite("theFileNameYouExpect.txt")).Returns(new StreamWriter(stream)).Verifiable();
    var manager = new Manager(fileSystemMock.Object);

    manager.SaveObject(new BObject(...));

    stream.Seek(0, SeekOrigin.Begin);
    Assert.That(...); // Perform asserts on the stream contents here
    fileSystemMock.Verify(); // Not really necessary, but verify that `OpenWrite` was called
}
2 голосов
/ 27 февраля 2011

По моему мнению, это зависит от того, сколько логики содержится в вашем классе.

Если в вашем менеджере есть какая-то сложная логика, имеет смысл абстрагировать ваши файловые операции в соответствии с предложением Aasmund, чтобы логику можно было протестировать независимо от файловой системы. Я делаю это, когда что-то достаточно привередливое, чтобы оправдать дополнительные зависимости.

С другой стороны, если очень мало логики, кроме обращения к вашему коду сериализации / десериализации, то часто допустимо пропускать модульные тесты и запускать интеграционные тесты, которые проверяют полный цикл (создать BObject в памяти, сохраните его, вызвав SaveObject, прочитайте его обратно, используя GetObject, убедитесь, что он равен / эквивалентен тому, который вы сохранили в первую очередь).

Если ваша среда сборки не может запускать интеграционные тесты, то я хотел бы настроить ее так, чтобы это было возможно.

...