WSDL.exe - генерирует интерфейс, а также конкретный класс для легкой подделки / издевательств - PullRequest
6 голосов
/ 15 сентября 2010

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

Мы используем сторонний веб-сервис из приложения ASP.Net и сгенерировали наши прокси-классы с использованием WSDL.exe.

Теперь я хочу написать тесты для моих классов-оболочек и бизнес-классов, подделав веб-сервис. У прокси нет интерфейса или абстрактного базового класса, и они помечены как внутренние, что означает, что я не могу унаследовать их, не вставив мой тестовый / поддельный тестовый код в мой бизнес-проект / сборки.

Я мог бы вручную создать интерфейс (используя resharper) и отредактировать класс, однако, если 3-я часть изменит свой WSDL / веб-сервис, мне или моим преемникам придется также вручную редактировать интерфейс и автоматически генерируемые классы, что никогда не кажется как хорошая идея.

Какой самый элегантный способ подделать или высмеять этот сервис? Стоит ли ставить подделку в бизнес-проекте? Должен ли я вручную редактировать файлы и создавать интерфейс? Должен ли я сделать что-то совершенно другое?

Ответы [ 3 ]

6 голосов
/ 15 сентября 2010

Правильно, в ответ на ответ Филиппа я остановился на одном и, возможно, нашел рабочее решение.Используя WSDL.exe, я сгенерировал интерфейсы (с помощью ключа / si) и обычных прокси-классов и добавил их в свой бизнес-проект.

Затем я создал новый класс, который наследуется отконкретный класс AND реализует интерфейс.Этот небольшой класс практически не содержал кода, поскольку унаследованные конкретные члены обеспечивали неявную реализацию членов интерфейса.Код скомпилирован впервые, и я смог заменить этот маленький класс «shim» («адаптер?») В моих интеграционных тестах и ​​выполнить вызовы с живого стороннего сервера.

Теперь я могу создавать другиеклассы (макеты или подделки), которые реализуют интерфейс, и заменяют их вместо класса "shim".

Редактировать: ОК, я немного поработал над этим и за исключениемнесколько осложнений это работает.

Первая значительная проблема заключается в том, что прокси-классы по-прежнему помечены как «внутренние», поэтому производный класс (адаптер / прокладка) также должен быть внутренним.Это не проблема, если вы добавляете класс Factory в свой бизнес-проект / сборку, который создает прокси-классы, и возвращает их в качестве интерфейса.

Вторая найденная проблема заключалась в том, что мы устанавливали URLи свойства тайм-аута веб-службы в явном виде, но они не включены в интерфейс, вместо этого они наследуются от System.Web.Services.Protocols.WebClientProtocol через SoapHttpClientProtocol.Опять же, я имел дело с этим на заводе, так как это деталь реализации, которой я доволен, не в интерфейсе.

Редактировать: Это все еще хорошо работает для меня при тестировании и разработке нашего Фасада,С тех пор как я получил прокси-интерфейс за интерфейсом, я также создал класс декоратора журналирования, который захватывает множество примеров вызовов для отладки использования и когда сторонний сервер отключен.

Я написал то, что ясделал чуть более подробно здесь: http://www.flowerchild.org.uk/archive/2010/09/21/mocking-or-faking-or-maybe-stubbing-a-wsdl-exe-soap.html

3 голосов
/ 15 сентября 2010

Вы можете запустить wsdl с ключом /serverinterface или /si, чтобы получить интерфейсы для каждой привязки в wsdl. Это должно дать вам серверный скелет из документа wsdl, но интерфейсы должны помочь вам в этом - если я правильно понимаю вопрос.

РЕДАКТИРОВАТЬ - После прочтения комментария, я считаю, что я неправильно понял вопрос - вы хотите, чтобы клиентский интерфейс / конкретный, чтобы вы могли кодировать контракт, а не реализацию. Переключатель /si, вероятно, вообще не даст вам того, что вы хотите.

Я не знаю ни одного переключателя, который может дать вам такое поведение, поскольку wsdl в основном создает одну из трех вещей: 1) прокси-классы клиента: 2) абстрактные классы сервера (для создания серверной реализации) 3) интерфейсы сервера ( опять же, для создания серверной реализации - это просто iface вместо абстрактного класса) Я не вижу способа заставить клиентские прокси-классы реализовывать интерфейсы (кроме INotifyPropertyChanged для типов данных)

1 голос
/ 15 сентября 2010

Я всегда обнаруживал, что эти сгенерированные классы слишком велики, чтобы их легко смоделировать (слишком много методов / свойств).

Вместо этого создайте Facade или Repository, который реализует только те вызовы, которые вам нужны, и передает обратноОбъекты стиля DTO с только теми свойствами, которые вам нужны.

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

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

...