2011-01-20 3 views
4

У меня есть закрытый класс с защищенными методами, поведение которых я хочу проверить. Это затрудняет прямое тестирование, и трудно издеваться.C#: Стыковка и тестирование защищенных (или закрытых) методов в закрытых классах - подходы

Это код, который не был разработан в TDD, и теперь я добавляю модульные тесты для определенной функциональности.

Каковы общие подходы в этом случае? На данный момент у меня есть:

  1. Имейте класс незапечатанным. Затем создайте прокси или адаптер, полученные из класса в нашем тестовом коде, чтобы туннелировать доступ к защищенному методу.
  2. Оцените поведение в защищенном методе делегата/функтора и заново вставьте его. Затем проверьте поведение, основанное на фактах, независимо.
  3. Тестирование путем вызова ближайшего общедоступного метода в иерархии наследования, использующего защищенный метод. Потенциально приводит к большому количеству насмешек и подверженности риску, когда код отличается от кода, находящегося под контролем теста, - создание хрупких тестов.
  4. Используйте отражение, чтобы получить доступ к защищенному методу. Затем позвоните прямо.

Есть ли еще?

ответ

7

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

И нет никаких испытаний точки private методов. Поскольку они не имеют поведения public, за исключением того, что доступно через методы определяющего класса, их поведение должно быть проверено путем тестирования методов public.

+0

несколько раз, чтобы протестировать общедоступный метод, удобно издеваться над личным методом. Я думаю, что это основной случай использования – anthares

+0

@anthares: Это звучит ошибочно. Если метод 'private' является частью реализации метода' public', его не следует издеваться. – jason

+0

Ну, давайте приведу вам пример: мне просто нужен хороший полудневный день, чтобы даже приблизиться к издевательствам всего, что мне нужно, просто называть определенный защищенный метод напрямую, используя отражение. Если мне нужно высмеять все из ближайшего публичного метода, мне, возможно, придется передать задачу моим детям для завершения. Это не значит, что я не согласен с вами в целом - просто с некоторыми кодовыми базами существуют и другие практические ограничения. (и +1) –

1

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

+0

Handy, ta; На данный момент я использую Rhino Mocks. –

2

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

3

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

И почему вы должны тестировать частные/защищенные методы? Для этого вы можете использовать внутренние методы и InternalVisibleToAttribute. Но в целом вы должны проверять только общественное поведение (т. Е. Только открытый интерфейс).

+0

Спасибо за указатель Moles, очень интересно. Я быстро ответил Джейсону насмешливым публичным методам. –

1

Вы можете использовать инфраструктуру JustMock. Например:

double value = 0; 
var fakeFilterSetHelper = Mock.Create<FilterSetHelper>(Behavior.CallOriginal); 
Mock.NonPublic.Arrange<double>(fakeFilterSetHelper, memberName: "GetPriceRangeFromSession").Returns(value);