2009-12-10 4 views
4

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

В моем случае у меня есть класс обслуживания, который содержит несколько методов/операций обслуживания. Цель класса сервиса - предоставить интерфейс для поведения, который реализуется в основном приложении. Таким образом, каждый метод/операция отвечает за:

  1. принимает объект запроса от вызывающего абонента
  2. компостера свойств объекта
  3. создание экземпляра применимого объекта Command, который выполняет операцию
  4. сопоставление свойств объекта Request объекта с объектом Command.
  5. выполнения команды объект
  6. отображения результатов в ответ объект
  7. возвращая ответ вызывающей

Кроме того, метод обслуживания обрабатывает любые исключения, возникающие и возвращающие WCF Fault.

Мы используем Spring.NET для IoC (DI) и АОП. Класс службы создается экземпляром Spring, который позволяет нам использовать параметр ParameterValidation Spring для выполнения шага 2. По умолчанию мы используем Spring для шага 3.

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

Давайте будем ясны, у меня нет проблем, издевающихся над объектами Command (мы используем Moq, btw), и у меня нет проблемы с тестированием черного ящика. Я пытаюсь выполнить проверку белого ящика во внутренней логике, например, чтобы убедиться, что шаг 4 выполняется правильно или если объект Command создает исключение, служба обрабатывает его правильно. Для них я использую макеты экземпляров объекта Command.

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

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

Служба предназначена для делегирования шага 4 виртуальному методу, который по умолчанию использует Spring для создания экземпляра объекта Command, но van переопределяется для возврата макета с использованием подхода наследования и переопределения. Но это оказалось громоздким.

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

Имейте в виду, что я не могу использовать Spring, чтобы вводить насмешливые объекты Command, потому что мне нужны ссылки на макеты для их настройки и проверки поведения метода. (Не говоря уже о том, что мои тесты затем зависят от правильной работы пружины тоже.)

+0

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

+0

Звучит скорее как функциональный тест, чем тот, который мы ищем. На самом деле, я должен был бы более четко указать, что я пытаюсь проверить реализацию класса обслуживания как «единицы». Я даже не использую WCF на данный момент. – SonOfPirate

ответ

0

Похоже, вы уже выполнили большую часть трудных работ.

Поскольку вы уже используете контейнер DI, возможно, вы можете просто создать и ввести Mocks, который перехватит шаг 3. Затем вы можете получить то, что получено контейнером DI, и как проведет проверку, чтобы проверить первые два шага, после чего вы могли бы Mock возвращает все, что вы хотите проверить оставшиеся шаги.

Вы уже в значительной степени зависели от spring.net и выбрали это дополнительное расстояние, чтобы придать своим издевательствам и силовым испытаниям, чтобы они звучали разумно для меня. Должен быть способ временно изменить вашу конфигурацию для использования определенного Mock. Если вы не считаете простой завод, который будет использоваться вашим сервисом, чтобы вы могли получить свои Mocks.

+0

Я понимаю, что я только что повторил ваш последний абзац, но если spring.net мешает тестированию, тогда обходите его. – smaclell

1

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

+0

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

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