Модульное тестирование C # рефакторинг статических методов - PullRequest
1 голос
/ 03 апреля 2012

У меня есть несколько классов (назовите это Class A), которые я хотел бы протестировать, но он использует некоторые классы (назовите его Class B) с некоторыми статическими методами.

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

Проблема в том, что у класса А есть много услуг (не только у класса В), от которых, похоже, зависит?

Каков наилучший вариант в этом сценарии? У вас есть конструктор с множеством параметров, которые могут принимать эти службы?

Или что-то не так с моим дизайном в том, что класс А имеет так много зависимостей?

Спасибо

Ответы [ 2 ]

5 голосов
/ 03 апреля 2012

Проблема в том, что в классе A есть много служб (не только в классе B), от которых он зависит?

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

Попробуйте разбить класс на более мелкие классы.

Модульные тесты являются хорошим показателем качества.Классы, которые сложно протестировать, часто нарушают один или несколько принципов SOLID.

Каков наилучший вариант в этом сценарии?У вас есть конструктор с множеством параметров, которые могут принимать эти службы?

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

2 голосов
/ 03 апреля 2012

Я бы порекомендовал внедрение конструктора, особенно если у вас есть много зависимостей для внедрения, только если вы используете платформу Dependency Injection, такую ​​как Unity или Ninject. Рефакторинг существующей кодовой базы для добавления инжектора конструктора везде обычно грязный, и, вероятно, требует хранения всех сервисов в локальных переменных во многих базовых классах, просто чтобы вы могли передать их классам дальше по цепочке.

В этом случае я бы использовал некоторую реализацию шаблона ServiceLocator с одним статическим классом ServiceLocator / Container, который вы можете использовать для доступа к вашим нестатическим службам:

IService _service = ServiceLocator.GetService<IService>();

Для этого потребуется минимальный объем рефакторинга в существующем коде (просто замените MyService.DoSomething() на _service.DoSomething(), и все же вы сможете смоделировать и протестировать свой код, заменив интернет-коллекцию ServiceLocator:

ServiceLocator.Register<IService>(myFakeService);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...