Как выполнить юнит-тестирование класса, для которого нужен определенный файл - PullRequest
10 голосов
/ 03 марта 2012

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

Я использую C # с NUnit.Пока у меня есть два теста:

[Test]
public void ShouldAllowInstanceToBeCreatedWhenXMLFileIsPresent()
{
    if (File.Exists(SettingsReader.XML_SETTINGS_PATH))
    {
        SettingsReader settingsReader = new SettingsReader();
        Assert.AreNotEqual(null, settingsReader);
    }
}

[Test]
[ExpectedException("Telekanzlei.Clientmanager.XMLDataLayer.XMLFileNotFoundException")]
public void ShouldThrowExceptionWhenXMLFileIsNotPresent()
{
    if (!File.Exists(SettingsReader.XML_SETTINGS_PATH))
    {
        SettingsReader settingsReader = new SettingsReader();
    }
        else
            throw new XMLFileNotFoundException();
    }

Я не уверен, что проверка наличия файла в тесте - это правильный путь, поэтому любые предложения по этому тесту также приветствуются.Но мой вопрос в том, как пройти следующие тесты.Очевидно, что все последующие тесты будут провалены, если XML-файл отсутствует.

Итак, я предполагаю, что XML-файл присутствует, имея в виду, что провальный тест может просто означать, что его нет?Мне бы это не показалось правильным.

Существует ли общая схема решения такой проблемы?

Спасибо за любую помощь

edit: переписал второй тест, поскольку он не работал, если файл действительно присутствовал ...

edit2: Может, он помогает вам сказать, что на самом деле делает SettingsReader.Пока это выглядит так:

public class SettingsReader
{
    public static readonly string XML_SETTINGS_PATH = "C:\\Telekanzlei\\Clientmanager_2.0\\Settings.xml";

    public XElement RootXElement { get; private set; }

    public SettingsReader()
    {
        if (!File.Exists(XML_SETTINGS_PATH))
            throw new XMLFileNotFoundException();
        using (var fs = File.OpenRead(XML_SETTINGS_PATH))
        {
            RootXElement = XElement.Load(fs);
        }
    }


}

Я не уверен, но я думаю, что StreamReader не был бы подходящим способом, не так ли?

Ответы [ 4 ]

14 голосов
/ 03 марта 2012

Проблема не в ваших юнит-тестах, а в дизайне класса.Я бы предложил рефакторинг класса, чтобы он не открывал файл, а работал с потоком.Тогда ваши модульные тесты могут просто заменить поток файлов на поток памяти - просто!:)

public class SettingsReader()
{
    public SettingsReader(System.IO.StreamReader reader)
    {
        // read contents of stream...
    }
}

// In production code:
new SettingsReader(new StreamReader(File.Open("settings.xml")));

// In unit test:
new SettingsReader(new StringReader("<settings>dummy settings</settings>"));

Помните, что открытие файла и анализ данных настроек - это две очень разные проблемы.

5 голосов
/ 03 марта 2012

Если вам нужно, я предлагаю вам использовать метод SetUp , чтобы скопировать или проверить, существует ли файл.Я рекомендую убедиться, что файл присутствует, добавив его в тестовый проект и пометив его как «всегда копировать», как только вы начнете работать, поэтому нет необходимости перепроверять его.
Если у вас много тестов, которые требуютвнешние файлы, возможно, вам следует использовать MsTest - он имеет атрибут DeploymentItem , который гарантирует, что файл будет скопирован в то же место, что и тест.

3 голосов
/ 03 марта 2012

Подумайте о переписывании кода, чтобы можно было передавать зависимости или как-то иначе указывать код, который вы хотите протестировать.

т.е. передать что-то вроде экземпляра «IMySettingsFileProvider» в конструктор SettingsReader, где IMySettingsFileProvider.SettingsXml возвращает поток настроек. Таким образом, вы можете смоделировать интерфейс IMySettingsFileProvider для теста, вместо того, чтобы требовать наличия файла на диске.

1 голос
/ 03 марта 2012

Один из вариантов - поместить это наверх тестового прибора.Тогда тесты будут действительны только при наличии файла.

[SetUp]
public void Setup()
{
    Assume.That(File.Exists(SettingsReader.XML_SETTINGS_PATH));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...