Monday, September 28, 2009

Mocking WCF Services

In my last post I showed how to decouple the service consumer from the service proxy using the ServiceLocator pattern.

In order to mock the WCF service, it is necessary to create the following ServiceClientStub:

public class ServiceClientStub<TServiceInterface> : IServiceClient<TServiceInterface>
        where TServiceInterface : class
{
  private TServiceInterface serviceMock;

  public ServiceClientStub(TServiceInterface serviceMock)
  {
    this.serviceMock = serviceMock;
  }

  public TServiceInterface Service 
  {
    get { return serviceMock; }
  }

  public void Dispose() { }
}

This allows you to test the service consumer without the service implementation (using Moq):

var result = ...
var mock = new Mock<IServiceA>();
mock.Setup(s => s.Operation()).Returns(result);
ServiceLocator.Register<IServiceClient<IServiceA>>(
    () => new ServiceClientStub<IServiceA>(mock.Object));

Tuesday, September 8, 2009

Using ServiceLocator to call a WCF Service

In my last post, I published a simple ServiceLocator, it may help you to decouple the service consumer from service proxy.


To do this, it is necessary to create a generic interface:


public interface IServiceClient<TServiceInterface> : IDisposable
        where TServiceInterface : class
{
  TServiceInterface Service { get; }
}


And it is the implementation using the ClientBase of WCF:


public class ServiceClient<TServiceInterface> :
       ClientBase<TServiceInterface>,
       IServiceClient<TServiceInterface>
       where TServiceInterface : class
{
  public TServiceInterface Service
  {
    get { return base.Channel; }
  }

  void IDisposable.Dispose()
  {
    try
    {
      base.Close();
    }
    catch (CommunicationException)
    {
      base.Abort();
    }
    catch (TimeoutException)
    {
      base.Abort();
    }
    catch (Exception)
    {
      base.Abort();
      throw;
    }
  }
}


Then, you can register and use the ServiceClient this way:


// Service Registration
ServiceLocator.Register<IServiceClient<IServiceA>>(() => new ServiceClient<IServiceA>());   

// Service Resolving
using (var client = ServiceLocator.Resolve<IServiceClient<IServiceA>>())
{
  client.Service.Operation();
}