2014-10-23 2 views
1

Использование C#Должны ли защищенные методы быть проверены на единицу? Как избежать повторного тестирования?

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

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

+1

A (не обязательно лучший) способ состоит в том, чтобы получить класс и обеспечить хорошо известное поведение в этом классе. Все, что вы сейчас тестируете, - это базовый класс. Хорошо известное поведение необходимо избегать тестирования тестового класса или его интеграции при его получении в реальных классах. – Samuel

+1

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

ответ

4

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

Что касается повторяющихся испытаний, у меня нет окончательного ответа. Если Дано:

public class A 
{ 
    protected virtual void Foo() {} 
} 

public class B:A 
{ 

} 

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

С другой стороны, A.Foo может зависеть от некоторых других protected полеев или свойств, которые B могут изменять, или на частный обратный вызов, который B обеспечивает в конструкторе или инициализации функции. В этом случае вам абсолютно необходимо проверить B.Foo, потому что его поведение может быть отличным от A.Foo, хотя B не переопределяет A.Foo.

Очевидно, что если B переопределяет Foo, вам необходимо написать тест для B.Foo. Но если B не переопределяет A.Foo, тогда вы должны использовать свое мнение.

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

+1

И повторите ли вы код, если его вызовут другие функции или унаследованные классы? –

+0

@EliezerSteinbock: см. Мой обновленный ответ –

0

Существует много мнений относительно того, что должно быть Unit Test, а что нет. Мое личное убеждение в том, что для каждой функции, которую вы пишете, вы должны сначала написать единичный тест, чтобы указать желаемое поведение. Затем вы пишете свой код, чтобы пройти этот тест. Это применимо для частных, общественных, защищенных и внутренних. Если он используется, он должен быть протестирован. Поверьте, это облегчает вашу жизнь в долгосрочной перспективе, потому что, если вы или другой разработчик меняете существующий код, проверенный модулем, то изменение поведения намного вероятнее будет поймано.

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

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