Простой способ издеваться над сервисом WCF?
-
03-07-2019 - |
Вопрос
У меня есть приложение, которое использует службу WCF.Теперь я хотел бы добавить модульные тесты в приложение.
В некоторых случаях мне нужно издеваться над службой WCF, поскольку добиться желаемого поведения от службы иногда бывает сложно (напримерслужба выдает специальные исключения).
Я мог бы добавить еще один интерфейс к клиенту wcf, но это кажется немного глупым, поскольку клиентские вызовы уже используют интерфейс.
Есть ли простой способ издеваться над службой WCF?Проще, чем создать еще один уровень интерфейса и перенаправлять каждый отдельный вызов WCF внутри него?
Редактировать:Большинство ответов, похоже, мало что знают об использовании сервиса WCF, поэтому некоторые пояснения:
Чтобы использовать службу WCF из ViewModel, я должен управлять подключением примерно так:
ChannelFactory<IMyWcfService> channelFactory = new ChannelFactory<IMyWcfService>("");
IMyWcfService proxy = channelFactory.CreateChannel();
proxy.CallMyStuff();
proxy.Close();
Я не могу просто передать ViewModel прокси-сервер WCF, поскольку соединение должно открываться и закрываться для каждой транзакции.По этой причине использование RhinoMock / NMock не будет работать, поскольку им нужна ViewModel, которая получает прокси в качестве параметра, что невозможно сделать подобным образом, если вы используете WCF.
Решение
Почему вы не можете использовать что-то вроде NMock2 чтобы поиздеваться над IMyWcfService
напрямую взаимодействует?
Если вам нужно иметь возможность создавать новые экземпляры "на лету", используйте фабрику, чтобы скрыть ChannelFactory<IMyWcfService>
от клиента.Таким образом, вы можете заменить фабрику, предоставив клиенту ту, которая создает mocks вместо реальных прокси.
Другие советы
Вы можете использовать любой фреймворк-макет, такой как RhinoMocks или NMock, для макетирования контракта интерфейса, поэтому, если в вашем сервисе реализован IMyService, вы могли бы использовать фреймворк-макет для установки ожиданий в отношении вызовов методов в этом интерфейсе.Если вы не знакомы с этой концепцией, то вы можете просто создать резервный объект, который реализует IMyService, но притворяется реальным сервисом во время вашего тестирования.Таким образом, когда методы вызываются, они вызываются для вашего резервного объекта, и вы можете получить от своего резервного объекта все, что захотите.
Ты можешь, ты Moq
издевательский фреймворк.Основываясь на примере, который вы предоставили:
ChannelFactory<IMyWcfService> channelFactory = new ChannelFactory<IMyWcfService>("");
IMyWcfService proxy = channelFactory.CreateChannel();
proxy.CallMyStuff();
proxy.Close();
Вот как будет выглядеть имитирующая реализация:
Mock<IMyWcfServiceChannel> channelMock = new Mock<IMyWcfServiceChannel>(MockBehavior.Strict);
channelMock
.Setup(c => c.CallMyStuff())
.Returns("");
string myStuff = channelMock.Object.CallMyStuff();
После того, как вы добавите прокси-сервер для WCF
сервис - у вас должен быть channel
доступный вам интерфейс, называемый IMyWcfServiceChannel
.
В зависимости от типа возвращаемого метода обслуживания, который вы вызываете, вы можете установить практически любой результат.В приведенном выше примере я использовал string
введите в качестве примера.
Чтобы более эффективно использовать приведенное выше решение, вы можете захотеть создать 2 конструктора для бизнес-уровня следующим образом:
public class Example1
{
IMyWcfServiceChannel _client;
public Example1()
{
var factory = new ChannelFactory<IMyWcfServiceChannel>("binding");
_client = factory.CreateChannel();
}
public Example1(IMyWcfServiceChannel client)
{
_client = client;
}
public string CallMyStuff()
{
return _client.CallMyStuff();
}
}
Итак, на prod
вы используете конструктор без параметров.В unit
тесты, в которых вы используете конструктор с полным параметром и передаете ему макет (channelMock.Object
).