Юнит тестирование приватным методом - PullRequest
1 голос
/ 07 февраля 2012

Прежде всего, я знаю, что есть много вопросов по этой теме. Я прочитал большинство из них, но я действительно не знаю, является ли это отсутствием надлежащего ОО-программирования, или я что-то упускаю.

Итак, у меня есть класс xmlRead, который считывает XML-файл в несколько списков. Я хочу провести модульное тестирование этого класса. Я считаю, что самый простой способ начать это проверить addDataToList(). Но это частный метод. Поэтому мне интересно, должен ли я сделать его общедоступным или протестировать открытый метод ReadTheXmlFile ().

public class xmlRead 
{
    List<string> ... // A couple of lists that need to filled with data from the XML document
    xmlDocument xDoc = new xmlDocument

    public void ReadTheXmlFile()
    {
        // Find default file, if it doesn't exist, ask user for file through Openfiledialog
        // and open XMLDocument + error handling if XMLdocument is empty etc.
        xDoc.load(filepath);
        takeInXmlData();
    }

    private void takeInXmlData()
    {
        addDataToList(list<string> list1, xmlNode 1);
        // More addDataToList for different lists
        ...
        addDataToList(list<string> list2, xmlNode 2);
    }

    private void addDataToList(list<string> inputList, xmlNode)
    {
         foreach (XmlNode node in xmlDoc.SelectNodes(xmlNode))
         {
             inputList.Add(node.SelectSingleNode("Specific name of node").InnerText);
         }
    }

Поэтому я попытался разделить вещи как можно больше. Но это также означает, что мой метод addDataToList очень мал, но прост в модульном тестировании. Но я также считаю, что это не должен быть публичный метод. Конечно, я мог бы протестировать публичный метод ReadTheXmlFile(), но тогда мне пришлось бы делать конкретные тестовые случаи для каждого результата обнаружения ошибок, и, по моему мнению, я бы не проверял должным образом фактическое поступление данных в список.

Я слишком чрезмерно защищен и должен ли я сделать addDateToList (или takeInXmlData) публичной? Или я должен просто протестировать публичный метод ReadTheXmlFile, пока не учту все возможные способы?

Это похоже на большую работу, которая идет вразрез с принципом коротких, простых юнит-тестов.

PS: Не нужно беспокоиться о том, что я загружаю xDoc прямо здесь, у меня есть Интерфейс, который управляет загрузкой XML-документа (который я могу заглушить позже, чтобы сломать зависимости). Основное внимание здесь уделяется приватным методам.

Ответы [ 4 ]

4 голосов
/ 07 февраля 2012

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

3 голосов
/ 07 февраля 2012

Отражение позволяет вам вызывать приватные методы и читать или писать приватные поля извне класса, но действительно многословно писать.

В C # 4.0 эта проблема может быть решена аккуратно с помощью динамического

Если вы можете использовать C # 4.0 в своих модульных тестах, прочитайте эту статью:

Тестирование частных методов с C # 4.0

Aпростое использование:

public class Service {
    private int Step1() {
        return 1;
    }
}

[TestClass]
public class TransparentObjectTests {
    [TestMethod]
    public void PrivateMethod() {
        dynamic s = new Service().AsTransparentObject();
        Assert.AreEqual(1, s.Step1());
    }
}
1 голос
/ 07 февраля 2012

Ваш addDateToList метод - это деталь реализации. То, что вы хотите и должны проверить это метод ReadTheXmlFile. Вы даже уже заметили, что следует проверять:

Найти файл по умолчанию, если он не существует, спросить пользователя о файле через Openfiledialog и открыть XMLDocument + обработка ошибок, если XMLdocument пуст и т. Д.

  • проверить, что происходит при сбое поиска (это звучит как задание внешней зависимости)
  • проверка ошибок обработки
  • тестовый XML-документ пустой
  • проверка свойства XML возвращается в случае успеха (это неявно проверяет частные методы)

А по этому поводу:

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

Это то, что вы действительно должны делать. Если ваш метод имеет несколько возможных ошибок, каждый из них должен быть протестирован. Это не становится проще, чем это. Большинство сред делают это (множественное тестирование ввода / вывода) действительно простым с такими атрибутами, как NUnit's TestCase .

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

0 голосов
/ 07 февраля 2012

вы можете попробовать,

Откройте файл AssemblyInfo.cs.Добавьте этот код,

[assembly: InternalsVisibleTo("Your Test Library Name")]

Затем измените private-to-internal

, вы можете написать тест для ваших внутренних методов в классе XmlRead.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...