2015-10-05 3 views
0

У меня есть публичный метод недействительного ниже:модульного тестирования на общественной ничтожной метод, который обновляет частный член

public void Reset() 
{ 
    // Get updates 
    // update logic for each value in _dict 
} 

в то время как _dict является частным членом класса:

private readonly dictionary<string, string> _dict; 

Как я могу выполнить блок проверить на логике обновления метода Reset()? Как я могу проверить значения в _dict правильные после сброса? Я не хочу настраивать публичный getter для _dict, чтобы разоблачить его.

Я использую xunit и C#.

+4

Тестирование через публичный API: http://blog.ploeh.dk/2015/09/22/unit-testing-internals. Создайте свой API соответствующим образом. –

ответ

5

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

В вашем конкретном случае мы не получаем полную информацию. Эффекты Reset() должны наблюдаться вне класса, иначе вам не нужен этот метод.

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

UPDATE: Всегда делайте то, что Марк Seemann говорит вам, потому что он является инвариантным право :)

1

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

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

Так что спросите себя, почему вы добавили метод public Reset() в свой класс? Почему клиенты вашего класса называют этот метод?

Например, если вы используете частный словарь для реализации какого-то кеширования, а метод Reset() очищает кеш, вымахивает ваш репозиторий и тестирует, получая свежие данные после вызова Reset().

Если вы не можете найти способ протестировать эффекты вызова с помощью общедоступного интерфейса вашего класса, вам не нужен этот метод. Удали это. Меньше кода = упрощение обслуживания.

0

Возможно, вы могли бы использовать шаблон Test Specifc Subclass, расширяющий класс и подвергая частный член или создавая открытый метод, который выставляет результат.

Подробнее: http://xunitpatterns.com/Test-Specific%20Subclass.html

Надеется, что это помогает.