2013-05-30 6 views
1

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

Я не хочу, чтобы сделать метод общественности как вопрос этот основные моменты:

Making a private method public to unit test it...good idea?

Мой вопрос будет, каковы различные способы тестирования частных методов и какой метод я должен благоприятствовать и почему?

Я прочитал этот вопрос (How do you unit test private methods?), но хотел бы знать, является ли принятый ответ по-прежнему лучшим ответом или через годы существует лучший способ.

Если этот вопрос считается дубликатом How do you unit test private methods?, я добавлю свой комментарий и прошу обновить его, пожалуйста, сообщите.

+0

Используйте метод отражения – user1283633

+1

взгляд на это http://bugsquash.blogspot.it/2009/05/testing-private-methods-with-c-40.html –

+0

@FabioMarcolini выглядит интересно, я поближе , –

ответ

1

Вы хотите, чтобы иметь возможность называть ваш частный метод в тесте и посмотреть, как он работает?

Вы можете получить свой класс и добавить общедоступный метод, который вызовет метод, который вы хотите проверить. Очень просто. Хотя я бы не советовал тестировать частные методы. Я не могу придумать ни одной причины для этого. Мне бы хотелось увидеть пример, который изменит мой разум.

+0

+1 Да, я согласен, мне не очень нравится тестировать частный метод в изоляции из-за хрупкости, которую он вводит в будущем, если вызывающий метод каким-то образом изменяется, в этом случае нет никаких тестов, охватывающих это, но я думаю, что я будет на самом деле наследовать и называть базовые реализации, проходящие через полный поток, хотя я буду издеваться над довольно большим количеством внутренних компонентов и позволить тестированию развиваться по мере изменений в будущих версиях. –

+0

То, что я сделал в конце концов, заключалось в том, чтобы получить класс, который я хотел протестировать, и сделал переопределение моего частного метода, захватил вход и выход и использовал те, которые были в моем тесте. –

+1

Существует даже название того, что вы сделали - «Извлечь и переопределить» –

2

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

Я бы избегал принятого ответа.

Я могу перейти в тираду о тестировании публичного интерфейса и не беспокоиться о внутренностях, но это может быть нереалистично.

Есть два непосредственных варианта я вижу:

  • Отражение, чтобы увидеть метод, своего рода хак, но, по крайней мере, вы можете получить какой-то тест собирается. Это также, вероятно, самый легкий способ быстро работать.
  • Опишите поведение частного метода, используя что-то вроде шаблона стратегии и введя поведение в сам объект (или внесите объект new в соответствующую стратегию вручную). Этот отдельный элемент стратегии затем может быть проверен независимо.

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

+0

+1 Спасибо за ваш вклад, я тоже думал об отражении, но надеялся избежать его, если это возможно, поскольку, как я подозреваю, для этого потребуется значительная сумма усилий? –

+0

@Monkieboy Не очень, если вы делаете это только для небольшого количества предметов. Конечно, код более подробный и не является строго типизированным или что-то еще, но вы можете рассматривать это как компромисс OK. –

7

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

Возможно, у вас есть возможность реорганизовать код, чтобы частные методы стали общедоступными методами некоторых других классов. Хорошим примером является класс, который планирует работу над таймером, который будет обработан позднее. Метод работы, скорее всего, будет реализован как частный метод, который затрудняет тестирование простым способом без планирования таймера и ожидания его выполнения для выполнения метода работы. Не идеальна в тесте, где время выполнения должно быть очень быстрым. Простым способом этого является разделение рабочего кода планирования на два отдельных класса.Затем частный метод работы становится общедоступным методом класса Worker, что делает его очень простым для тестирования. В то время как разделение графика планирования и рабочего кода означает, что вы будете бороться за 100% охват, вы, по крайней мере, покроете рабочий код. Путь к проблеме заключается в использовании чего-то типа Quartz.net для реализации класса планировщика, чтобы вы могли легко тестировать планировщик и рабочий код.

+0

+1 Да, вы правы, это может указывать на некоторые недостатки дизайна, но мои рассуждения состоят в том, что потребуется большая работа, чтобы написать тест для уже существующего бита функциональности, который является своего рода недоступным для текущего изменения I я делаю. Я хочу поставить тесты на место вокруг этого полностью, но не могу сделать это прямо сейчас. –

+0

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

-1

Использование отражения. Если вы не хотите сами себя отражать, тогда вы можете использовать класс PrivateObject от Microsoft, расположенный в Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll. Но есть проблемы в сотрудничестве с MSTest и NUnit - Using both MSTest and NUnit?

1

В VS 2005, 2008 и 2010 годах у вас может быть частный аксессуар. Вы щелкните правой кнопкой мыши на частной функции и выберите «Создать частный аксессор» ...

В VS 2012 эта функция как-то исчезла. Единственный удобный способ - использовать PrivateObject. Вы можете проверить MSDN на примеры использования PrivateObject.

0

Если вы используете VS 2005 или выше, используйте следующие шаги

  1. Открыть файл исходного кода, который содержит приватный метод.
  2. Щелкните правой кнопкой мыши частный метод и выберите «Создать тесты единиц измерения». Отображается диалоговое окно «Создать тесты единиц измерения». В видимой древовидной структуре выбирается только флажок для частного метода.
  3. (необязательно) В диалоговом окне «Создать тесты единиц измерения» вы можете изменить проект «Вывод». Вы также можете нажать «Настройки», чтобы изменить конфигурацию модульных тестов.
  4. Нажмите OK. Создает новый файл с именем VSCodeGenAccessors, который содержит специальные методы доступа, которые извлекают значения частных объектов в тестируемом классе. Вы можете увидеть новый файл, отображаемый в обозревателе решений в папке тестового проекта. Если ваш тестовый проект не имел модульных тестов до этого момента, также создается файл исходного кода для размещения модульных тестов. Как и в файле, который содержит частные аксессоры, файл, содержащий модульные тесты, также отображается в тестовом проекте в обозревателе решений.
  5. Откройте файл, содержащий ваши модульные тесты, и перейдите к тесту для частного метода. Найдите инструкции, помеченные // TODO: комментарии и заполните их, следуя указаниям в комментариях. Это помогает тесту более точных результатам

За дополнительной информацией обращайтесь this

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

+0

Спасибо @kleopatra, сделанные изменения. – Priyang

0

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

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

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

Смежные вопросы