Kash Farooq's software development blog

.NET Developer

Posts Tagged ‘WCF’

Stubbing RESTful services with WCF (Part 3)

Posted by Kash Farooq on July 9, 2012

A three part series.

  • Part 1: The set-up. Setting up an example to show what we are trying to stub.
  • Part 2: Creating a REST service stub.
  • Part 3: Using the service stub from a test.

In this final part of the series, I’ll use the ServiceStub class created in Part 2 to create a full end-to-end test.

I want to create an Order Query System that uses the data provided by the RESTful URI to return some consolidated data.

Here is a very simple example to start with – the Order Query System provides a method that calculates how old an order is.  My test code needs to bring up the service stub, populate it with some stub data, call the Order Query System and then stop the service stub.:

[TestFixture]
public class TestCode
{
  private ServiceStub serviceStub;

  [TestFixtureSetUp]
  public void TestFixtureSetUp()
  {
    serviceStub = new ServiceStub();
    serviceStub.Start();
  }

  [TestFixtureTearDown]
  public void TestFixtureTearDown()
  {
    serviceStub.Stop();
  }

  [Test]
  public void GetNumbersOfDaysSinceOrderPlaced()
  {
    DateTime orderDate = DateTime.Now.AddDays(-100);
    var order = new Order {Id = 1, OrderDate = orderDate, OrderLinesRef = "http://localhost:7000/OrderingSystem/Order/1/Orderlines" };
    serviceStub.Add(order);

    var orderQuerySystem = new OrderQuerySystem();
    var daysSinceOrderPlaced = orderQuerySystem.GetNumberOfDaysSinceOrderWasPlaced(1);

    daysSinceOrderPlaced.Should().Be(100);
  }
}

I bring the service stub up in the Test Fixture Set-up and close it down in the corresponding tear down method. In the test, I create some dummy data and add it to the stub. I then call the Order Query System  and do my my assert.

And the method in the OrderQuerySystem class:

public class OrderQuerySystem
{
  public int GetNumberOfDaysSinceOrderWasPlaced(int orderId)
  {
    var gateway = new RestServiceGateway();
    var order = gateway.GetOrder(orderId);
    return (DateTime.Now - order.OrderDate).Days;
  }
}

The Order Query System uses the RestServiceGateway (implementation omitted – I’ll give this at the end of the post for completeness) to get the data it needs to fulfil the query.

Here is an example that requires me to navigate to the child entity. I’ll call a Order Query System method that returns the number of order lines that a particular order has – this means I need to stub both the order and the order lines belonging to that order:

[Test]
public void GetNumbersOfOrderLinesForAnOrder()
{
   var order = new Order { Id = 2, OrderDate = DateTime.Now, OrderLinesRef = "http://localhost:7000/OrderingSystem/Order/2/Orderlines" };
   var orderLine1 = new OrderLine { Id = 21, OrderRef = "http://localhost:7000/OrderingSystem/Order/2"};
   var orderLine2 = new OrderLine { Id = 22, OrderRef = "http://localhost:7000/OrderingSystem/Order/2"};
   var orderLine3 = new OrderLine { Id = 23, OrderRef = "http://localhost:7000/OrderingSystem/Order/2"};
   var orderLines = new OrderLines {ArrayOfOrderLines = new[] {orderLine1, orderLine2, orderLine3}};
   serviceStub.Add(order);
   serviceStub.Add(order.Id,orderLines);

   var orderQuerySystem = new OrderQuerySystem();
   var numberOfOrderLines = orderQuerySystem.GetNumberOfOrderLinesFor(2);

   numberOfOrderLines.Should().Be(3);
}

And the corresponding method in the OrderQuerySystem class:

public class OrderQuerySystem
{
  public int GetNumberOfOrderLinesFor(int orderId)
  {
    var gateway = new RestServiceGateway();
    var order = gateway.GetOrder(orderId);
    var orderlines = gateway.GetEntity<OrderLines>(order.OrderLinesRef);
    return orderlines.ArrayOfOrderLines.Length;
  }
}

In the above example, the system under test code has to navigate to a child entity based on a ref provided by the parent entity.

And that’s it. On a recent project I’ve created some rock-solid integration tests using this technique.

For completeness, here is the RestServiceGateway class:

public class RestServiceGateway
{
  private const string EntityAddress = "http://localhost:7000/OrderingSystem/{0}/{1}";
  private const string ChildEntityAddress = "http://localhost:7000/OrderingSystem/{0}/{1}/{2}";

  public Order GetOrder(int orderId)
  {
    return GetEntity<Order>(string.Format(EntityAddress,"Order",orderId));
  }

  public OrderLine GetOrderLine(int orderlineId)
  {
    return GetEntity<OrderLine>(string.Format(EntityAddress, "Orderline", orderlineId));
  }

  public OrderLines GetOrderLinesFor(int orderId)
  {
    return GetEntity<OrderLines>(string.Format(ChildEntityAddress, "Order", orderId, "Orderlines"));
  }

  public T GetEntity<T>(string entityAddress)
  {
    var xmlSerializer = new XmlSerializer(typeof (T));
    var xmlReader = XmlReader.Create(entityAddress);
    var entity = (T) xmlSerializer.Deserialize(xmlReader);
    return entity;
  }
}
Advertisements

Posted in .NET, Test Driven Development, WCF | Tagged: , , , | Leave a Comment »

Stubbing RESTful services with WCF (Part 2)

Posted by Kash Farooq on July 9, 2012

A three part series.

  • Part 1: The set-up. Setting up an example to show what we are trying to stub.
  • Part 2: Creating a service stub.
  • Part 3: Using the service stub from a test.

Part 1 explained what we are trying to stub – and the first step in creating a service stub is to create a Service Contract interface that looks like the RESTful service we want to stub:

[ServiceContract]
public interface IServiceStub
{
  [WebInvoke(ResponseFormat = WebMessageFormat.Xml, UriTemplate = "OrderingSystem/{entityType}/{entityId}", BodyStyle = WebMessageBodyStyle.Bare, Method = "GET")]
  [OperationContract]
  XElement GetEntity(string entityType, string entityId);

  [WebInvoke(ResponseFormat = WebMessageFormat.Xml, UriTemplate = "OrderingSystem/{entityType}/{entityId}/{childEntityType}", BodyStyle = WebMessageBodyStyle.Bare, Method = "GET")]
  [OperationContract]
  XElement GetChildEntity(string entityType, string entityId, string childEntityType);
}

ServiceContractAttribute is in System.ServiceModel and WebInvokeAttribute is in System.ServiceModel.Web,

The UriTemplate properties in the Service Contract match the RESTful URIs we need to hit, e.g. http://localhost:7000/OrderingSystem/Order/2 (getting a specific order) and http://localhost:7000/OrderingSystem/Order/2/Orderlines (getting child order lines for a specific order).

Next we need a service stub that implements this interface:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class ServiceStub : IServiceStub
{
  public XElement GetEntity(string entityType, string entityId)
  {
    //TODO: implement
  }

  public XElement GetChildEntity(string entityType, string entityId, string childEntityType)
  {
    //TODO: implement
  }
}

Our tests will bring this service up (listening on port 7000) using WCF’s ServiceHost. The test code can then hit public methods that call down through application layers to the point where a layer would normally hit the RESTful service. However, rather than hitting the real service it will hit this stub.

So, we need a method in ServiceStub for the tests to call that will bring up the service and a corresponding method to stop it. Let’s add these method to the ServiceStub class:

private ServiceHost serviceHost;
public void Start()
{
  serviceHost = new ServiceHost(this, new Uri("http://localhost:7000"));
  var serviceEndpoint = serviceHost.AddServiceEndpoint(typeof(IServiceStub), new WebHttpBinding(), string.Empty);
  serviceEndpoint.Behaviors.Add(new WebHttpBehavior());
  serviceHost.Open();
}

public void Stop()
{
  serviceHost.Close();
}

ServiceStub will need to return stubbed data, so it needs methods to allow the tests to insert test data into the stub. Then, when GetEntity and GetChildEntity are called they can return that stubbed data. We’ll do this by providing a couple of Add methods to add Orders and Order Lines to the stub. I’ll store the stub data in dictionaries:

private readonly Dictionary<int, Order> orders = new Dictionary<int, Order>(); //key is order ID
private readonly Dictionary<int, OrderLines> ordersLinesDictionary = new Dictionary<int, OrderLines>(); //key is order ID
private readonly Dictionary<int, OrderLine> ordersLineDictionary = new Dictionary<int, OrderLine>(); //key is orderline ID
public void Add(Order order)
{
  orders.Add(order.Id,order);
}

public void Add(int orderId,OrderLines orderLines)
{
  foreach (var orderLine in orderLines.ArrayOfOrderLines)
  {
    ordersLineDictionary.Add(orderLine.Id,orderLine);
  }
  ordersLinesDictionary.Add(orderId,orderLines);
}

Finally, lets implement the GetEntity and GetChildEntity methods. They will take data from the dictionaries and serialize it – returning it as XML:


public XElement GetEntity(string entityType, string entityId)
{
  if (entityType=="Order")
  {
    return ObjectSerializer.Serialize(orders[Convert.ToInt32(entityId)]);
  }
  if (entityType=="Orderline")
  {
    return ObjectSerializer.Serialize(ordersLineDictionary[Convert.ToInt32(entityId)]);
  }
  throw new NotSupportedException();
 }

public XElement GetChildEntity(string entityType, string entityId, string childEntityType)
{
  if (entityType=="Order" && childEntityType=="Orderlines")
  {
    return ObjectSerializer.Serialize(ordersLinesDictionary[Convert.ToInt32(entityId)]);
  }
  throw new NotSupportedException();
}

When GetEntity or GetChildEntity is called, the code checks which entity was requested, grabs it out of the correct dictionary, serializes it with a helper class I created (see below) and returns it.

The final post in this series will demonstrate the usage of the Service Stub.

For completeness, here is the full ServiceStub class and the ObjectSerializer class:

public class ObjectSerializer
{
  public static XElement Serialize(object objectToSerialize)
  {
    using (var memoryStream = new MemoryStream())
    {
      var xmlSerializer = new XmlSerializer(objectToSerialize.GetType());
      xmlSerializer.Serialize(memoryStream, objectToSerialize);
      memoryStream.Flush();
      memoryStream.Seek(0, SeekOrigin.Begin);
      return XElement.Load(memoryStream);
    }
  }
}
<pre>[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class ServiceStub : IServiceStub
{
  private readonly Dictionary<int, Order> orders = new Dictionary<int, Order>(); //key is order ID
  private readonly Dictionary<int, OrderLine> ordersLineDictionary = new Dictionary<int, OrderLine>(); //key is orderline ID
  private readonly Dictionary<int, OrderLines> ordersLinesDictionary = new Dictionary<int, OrderLines>(); //key is order ID
  private ServiceHost serviceHost;

  public XElement GetEntity(string entityType, string entityId)
  {
    if (entityType == "Order")
    {
      return ObjectSerializer.Serialize(orders[Convert.ToInt32(entityId)]);
    }
    if (entityType == "Orderline")
    {
      return ObjectSerializer.Serialize(ordersLineDictionary[Convert.ToInt32(entityId)]);
    }
    throw new NotSupportedException();
  }

  public XElement GetChildEntity(string entityType, string entityId, string childEntityType)
  {
    if (entityType == "Order" && childEntityType == "Orderlines")
    {
      return ObjectSerializer.Serialize(ordersLinesDictionary[Convert.ToInt32(entityId)]);
    }
    throw new NotSupportedException();
  }

  public void Start()
  {
    serviceHost = new ServiceHost(this, new Uri("http://localhost:7000"));
    var serviceEndpoint = serviceHost.AddServiceEndpoint(typeof (IServiceStub), new WebHttpBinding(), string.Empty);
    serviceEndpoint.Behaviors.Add(new WebHttpBehavior());
    serviceHost.Open();
  }

  public void Stop()
  {
    serviceHost.Close();
  }

  public void Add(Order order)
  {
    orders.Add(order.Id, order);
  }

  public void Add(int orderId, OrderLines orderLines)
  {
    foreach (var orderLine in orderLines.ArrayOfOrderLines)
    {
      ordersLineDictionary.Add(orderLine.Id, orderLine);
    }
    ordersLinesDictionary.Add(orderId, orderLines);
  }
}

Right. We have our stub. Now on to Part 3 where we’ll use it from a test.

Posted in .NET, Test Driven Development, WCF | Tagged: , , , , | Leave a Comment »

Stubbing RESTful services with WCF (Part 1)

Posted by Kash Farooq on July 9, 2012

A three part series.

  • Part 1: The set-up. Setting up an example to show what we are trying to stub.
  • Part 2: Creating a REST service stub.
  • Part 3: Using the service stub from a test.

In this post I will provide the “set-up” for the later posts – basically this post will explain what I am trying to stub by giving some URI, Model and XML examples.

Firstly, here is the simple object model that the RESTful service returns as XML. Essentially we have an order which contains some order lines. Each order includes a URI to the child resource – i.e. to an array of order lines, and each order line has a URI back to the parent resource – i.e. to the parent order. I’m going to create a “Order Query System” – the system under test – that uses the RESTful service to retrieve data and I will need to stub it to create some robust and consistently repeatable integration tests.

public class Orders
{
  public Order[] ArrayOfOrders { get; set; }
}

public class Order
{
  public int Id { get; set; }
  public DateTime OrderDate { get; set; }
  public string OrderLinesRef { get; set; }
}

public class OrderLines
{
  public OrderLine[] ArrayOfOrderLines { get; set; }
}

public class OrderLine
{
  public int Id { get; set; }
  public string OrderRef { get; set; }
}

To get an order with ID=2, we hit the RESTful URI http://localhost:7000/OrderingSystem/Order/2. The following XML document returned is:

<?xml version="1.0" encoding="utf-8"?>
<Order xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Id>1</Id>
  <OrderDate>2012-06-03T19:14:06.4383397+01:00</OrderDate>
  <OrderLinesRef>http://localhost:7000/OrderingSystem/Order/2/Orderlines</OrderLinesRef>
</Order>

If the client then follows the OrderLinesRef URI to http://localhost:7000/OrderingSystem/Order/2/Orderlines, the following XML, containing all the order lines that belong to Order 2, is returned :

<?xml version="1.0" encoding="utf-8"?>
<OrderLines xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <ArrayOfOrderLines>
    <OrderLine>
      <Id>21</Id>
      <OrderRef>http://localhost:7000/OrderingSystem/Order/2</OrderRef>
    </OrderLine>
    <OrderLine>
      <Id>22</Id>
      <OrderRef>http://localhost:7000/OrderingSystem/Order/2</OrderRef>
    </OrderLine>
    <OrderLine>
      <Id>23</Id>
      <OrderRef>http://localhost:7000/OrderingSystem/Order/2</OrderRef>
    </OrderLine>
  </ArrayOfOrderLines>
</OrderLines>

Finally, if you hit the URI for a specific order line, e.g. http://localhost:7000/OrderingSystem/Orderline/22, the data just for order line 22 are returned:

<?xml version="1.0" encoding="utf-8"?>
<OrderLine xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Id>22</Id>
  <OrderRef>http://localhost:7000/OrderingSystem/Order/2</OrderRef>
</OrderLine>

Right. Now on to the next part 2: creating a Service Stub that returns data like the above XML examples for the various URIs.

Posted in .NET, Test Driven Development, WCF | Tagged: , , , , | Leave a Comment »

Sending large messages to a WCF Service

Posted by Kash Farooq on November 29, 2008

It took me several hours to sort out a problem when sending large messages to a WCF web service, looking for information at various websites. So I thought I’d summarise everything you need to do in one blog post.

We were getting errors such as “Bad Request” (HTTP Status 400) and .NET exceptions such as “System.ServiceModel.CommunicationException: The underlying connection was closed: The connection was closed unexpectedly. System.Net.WebException: The underlying connection was closed: The connection was closed unexpectedly”.

The fixes are all in the web.config
First configure the HTTP Runtime to accept large messages. Note – this is a denial of service risk. Our services are internal so I didn’t need to worry about this.

<system.web>
     <httpRuntime maxRequestLength="2097151" />
</system.web>

The rest of the configuration changes are in ServiceModel section. 2147483647 is the maximum for many values (the config items are Int32).
The config below will allow you to send a a large message. A large message that contains lots of objects (hence the maxItemsInObjectGraph) is streamed (transferMode=”Streamed”) in 0.5MB chunks (maxBufferSize=”524288″).The readerQuotas section allows large messages to be deserialized from XML into the service type.

<system.serviceModel>    
    <services>
	<service behaviorConfiguration="IncreasedItemsInObjectGraph"    
            name="ServiceName">
	    <endpoint address="" binding="basicHttpBinding" contract="ServiceName.IServiceContract" 
                   bindingConfiguration="BasicHttpBinding_IncreasedMessageSize_Buffered" />
	</service>
    </services>
    <behaviors>
	<servicebehaviors>
	   <behavior name="IncreasedItemsInObjectGraph">
		<servicemetadata httpGetEnabled="true" />
		<servicedebug includeExceptionDetailInFaults="true" />
			<datacontractserializer maxItemsInObjectGraph="2147483647" />
	   </behavior>
	</servicebehaviors>
    </behaviors>
    <bindings>
	<basichttpbinding>
		<binding name="BasicHttpBinding_IncreasedMessageSize_Buffered" 
                     maxBufferSize="524288" maxReceivedMessageSize="2147483647" 
                     closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:05:00" 
                     sendTimeout="00:05:00" transferMode="Streamed">
                     
                     <readerquotas maxDepth="2147483647" maxStringContentLength="2147483647"
                      maxArrayLength="2147483647" maxBytesPerRead="2147483647" 
                      maxNameTableCharCount="2147483647" />
		</binding>
	</basichttpbinding>
</bindings>
</system.serviceModel>

The client also needs similar settings:

<system.serviceModel>
	<bindings>
		<basichttpbinding>
			<binding name="BasicHttpBinding_IncreasedMessageSize_Buffered" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:05:00" sendTimeout="00:05:00" transferMode="Streamed" maxBufferSize="524288" maxReceivedMessageSize="2147483647">
				<readerquotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
			</binding>
		</basichttpbinding>
	</bindings>
    <behaviors>
      <endpointbehaviors>
        <behavior name="MoreItemsInObjectGraph">
          <datacontractserializer maxItemsInObjectGraph="2147483647" />
        </behavior>        
      </endpointbehaviors>
    </behaviors>
	<client>
		<endpoint address="http://localhost:409/Service.svc" binding="basicHttpBinding" contract="Service.IServiceContract" bindingConfiguration="BasicHttpBinding_IncreasedMessageSize_Buffered" behaviorConfiguration="MoreItemsInObjectGraph"/>      
	</client>
</system.serviceModel>

Posted in .NET, WCF | Tagged: | Leave a Comment »

Mocking WCF Services with Rhino Mocks

Posted by Kash Farooq on November 29, 2008

With WCF self-hosting it is easy to substitute an external service dependency with a mock service.
If you have code that calls an external web service, and you want to create an integration test that ensures that the external web service is called with the correct data, you can combine WCF self-hosting and a mocking framework to replace the external web service.
First, let’s create a pretend external web service that has one method that receives a complex type.

namespace TheService
{
    [ServiceContract]
    public interface IService
    {
        [OperationContract]
        Acknowledgement SubmitOrder(Order order);
    }

    [DataContract]
    public class Order {
        [DataMember]
        public int Id { get; set; }
        [DataMember]
        public IList OrderLines { get; set; }
    }

    [DataContract]
    public class OrderLine {
        [DataMember]
        public int Id { get; set; }
        [DataMember]
        public string Description { get; set; }
    }
}

The system under test uses this web service:

namespace TheClient {
    public class Facade {
        public bool SubmitOrder() {
            var order=new Order();
            order.Id = 1;
            order.OrderLines=new List();
            order.OrderLines.Add(new OrderLine{Description = "OrderLine1",Id = 1});
            order.OrderLines.Add(new OrderLine{Description = "OrderLine2",Id = 2});
            Acknowledgement acknowledgement;
            using (var serviceClient=new ServiceClient()) {
                acknowledgement = serviceClient.SubmitOrder(order);
            }
            return acknowledgement.Success;
        }
    }
}

Now we can write an integration test that makes sure we call the service with two order lines. First I create a class that implements the service contract. The methods do not need to be implemented as we will use Rhino Mocks to mock the behaviour – however notice that I had to make the method virtual so that I can use PartialMock. Also note the InstanceContextMode. It needs to set to “single” so that a mock service object can be loaded by ServiceHost.

namespace IntegrationTests {
   [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class PartialMockService : IService {
        public virtual Acknowledgement SubmitOrder(Order order) {
            throw new NotImplementedException();
        }
    }
}

Now I can create the test. The mock needs to be set up in the TestFixtureSetup so that the service is running throughout all the tests.
The test sets up expectations on the service mock, and checks the arguments that were sent to the service method.

    [TestFixture]
    public class PartialMockTheService {
        private ServiceHost host;
        private MockRepository mockRepository;
        private PartialMockService serviceMock;

        [TestFixtureSetUp]
        public void TestFixtureSetUp() {
            mockRepository = new MockRepository();
            serviceMock = mockRepository.PartialMock<PartialMockService>();
            host = new ServiceHost(serviceMock);
            host.AddServiceEndpoint(typeof (IService), new BasicHttpBinding(), "http://localhost:8093/Service.svc");
            host.Open();
        }

        [Test]
        public void FacadeShouldCallTheWebserviceWithTwoOrderLines() {
            serviceMock.Expect(x => x.SubmitOrder(new Order()))
                            .IgnoreArguments()
                            .Return(new Acknowledgement {Success = true});
            mockRepository.ReplayAll();
            var facade = new Facade();

            Assert.IsTrue(facade.SubmitOrder());
            IList argumentsForCallsMadeOn = serviceMock
                              .GetArgumentsForCallsMadeOn(x => x.SubmitOrder(null));
            var order = (Order) argumentsForCallsMadeOn[0][0];
            Assert.AreEqual(2, order.OrderLines.Count);
        }
    }
}

The unit test app.config needs the same Service Model confiuration settings as the system under test, with the service location altererd so that it points to your mock rather than the real service.

<system.serviceModel>
        <client>
            <endpoint
                    address="http://localhost:8093/Service.svc"
                    binding="basicHttpBinding"
                    contract="TheServiceProxy.IService" />
      </client>
</system.serviceModel>

I tried to do the same test but with DynamicMock rather than PartialMock. If you can get this to work you save some code as you won’t need to create PartialMockService. However, I could not get this to work. I got the error:

The service class of type IServiceProxyc688097f68fa4881a2eac45ad09283ba both defines a ServiceContract and inherits a ServiceContract from type TheService.IService. Contract inheritance can only be used among interface types. If a class is marked with ServiceContractAttribute, it must be the only type in the hierarchy with ServiceContractAttribute.

Basically, it appears as though the ServiceContract attribute is on both interface and dynamically created concrete. I did some brief investigation and I don’t think the problem is inside Rhino Mocks – I think it is in Castle’s DymanicProxy code that Rhino Mocks uses.

Related Posts

Stubbing RESTful services with WCF

Posted in .NET, Rhino Mocks, Test Driven Development, WCF | Tagged: , , | 1 Comment »