Модульное тестирование C #:Тестирование метода, использующего MapPath

StackOverflow https://stackoverflow.com/questions/1261729

Вопрос

Прежде всего, я осознаю, что этот вопрос опасно близок к:Как отобразить путь в модульном тестировании на C#

Однако я надеюсь, что у этого есть другое решение.Моя проблема заключается в следующем:

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

Поскольку MapPath находится в моем коде проверки, а не в моем модульном тестировании, как мне заставить мой модульный тест распознавать путь?Имеет ли смысл этот вопрос?

Строка ошибки (В моем проверочном коде, А НЕ в моем модульном тестировании):

XDocument xdoc = XDocument.Load(HttpContext.Current.Server.MapPath("App_Data/ErrorCodes.xml"));

Упрощенный:Модульный тест вызывает метод в моей программе, который вызывает Server.MapPath, который затем завершается с ошибкой.

Это было полезно?

Решение

Я бы выделил «поставщика имен файлов» в класс, который просто возвращает местоположение, и тогда вы сможете издеваться над ним намного проще.

public class PathProvider
{
    public virtual string GetPath()
    {
        return HttpContext.Current.Server.MapPath("App_Data/ErrorCodes.xml");
    }
}

Затем вы можете напрямую использовать класс PathProvider...

PathProvider pathProvider = new PathProvider();
XDocument xdoc = XDocument.Load(pathProvider.GetPath());

Или высмеивайте это в своих тестах:

PathProvider pathProvider = new MockPathProvider(); // using a mocking framework
XDocument xdoc = XDocument.Load(pathProvider.GetPath());

Другие советы

После тщательного поиска в Google и помощи коллеги мы придумали простое решение, уже встроенное в .net.

Над модульными тестами, которые обращаются к процессу проверки, я добавил:

 [TestMethod()]
 [HostType("ASP.NET")]
 [UrlToTest("http://localhost:###/upload_file.aspx")]
 [AspNetDevelopmentServerHost("Path To Web Application", "Path To Web Root")]

Это работает отлично.По сути, когда тест вызывается, он загружает URL-адрес с указанным модульным тестом при загрузке страницы.Поскольку модульный тест сейчас вызывает веб-сайт, проверка будет иметь доступ к Server.MapPath.Возможно, это решение подойдет не всем, но для этого оно идеально подошло.Спасибо всем, кто внес свой вклад.

Попробуйте использовать Rhino Mocks или альтернативный фреймворк для макетирования HttpContext (или других зависимых объектов) Или вы могли бы написать свои собственные макетные объекты.Или напишите класс MapPathWrapper, наследуйте от класса MapPathWrapperBase для вашей реальной среды, затем для ваших модульных тестов создайте объект MockMapPathWrapper.

Должно быть много примеров для насмешек над SO.

Вот один из них, который я задал:

Как использовать Rhino Mocks для создания макета HttpContext.Приложение

Обновить У меня есть опыт выполнения этого только с Asp.Net MVC, с webforms, я полагаю, это было бы намного сложнее из-за отсутствия класса HttpContextBase.

Я бы извлек методы, которые принимают ваши зависимости в качестве аргументов:

public void Validate(HttpContext context)
{
    ValidatePath(context.Server.MapPath("App_Data/ErrorCodes.xml"));
}

public void ValidatePath(string path)
{
    XDocument xdoc = XDocument.Load(path);
    ValidateDocument(xdoc);
}

public void ValidateDocument(XDocument xdoc)
{
    // Original code
}

Затем вы можете протестировать различные методы независимо.Например, тестирование того, как ValidatePath() обрабатывает отсутствующий файл.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top