Kash Farooq's software development blog

.NET Developer

Creating dynamic objects from XML in .NET 4

Posted by Kash Farooq on July 1, 2013

After looking at using dynamics to create objects from JSON in .NET 4, I wondered if you can do the same with XML.

I couldn’t find anything straight out of the box, but I did find this excellent sample code: Dynamic XML Reader with C# and .Net 4.0.

Here is a quick demonstration of what you can do with it.

With the following XML:

<quartzJobs>
 <job type="HelloWorld.HelloJob,HelloWorld" cronSchedule="0/5 * * * * ?" />
 <job type="HelloWorld2.HelloJob2,HelloWorld2" cronSchedule="0/7 * * * * ?" />
</quartzJobs>

You can do this:

dynamic jobConfig = new DynamicXml(File.ReadAllText("Jobs.XML"));
foreach (var job in jobConfig.job)
{
  Console.WriteLine(string.Format("Job to run: {0}. Schedule: {1}", job.type, job.cronSchedule));
}

Very nice. I reckon it is a lot less clunky than LINQ to XML.

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

Using Moq callbacks to check complex arguments sent to a dependency

Posted by Kash Farooq on June 16, 2013

I’ve written before about the various ways you can test the contents of a complex parameter sent to a dependency. The messages you see in RhinoMocks and Moq when a test fails aren’t always clear.

You can use Moq callbacks to give clear test failure messages.

Consider the system under test. Your creating an order, and using some of the data in the order object to create a customer. Obviously, you would have written this code test-driven – the aim of the test would be to ensure the customer object is created properly.

public class OrderService
{
  private readonly ICustomerService _customerService;

  public OrderService(ICustomerService customerService)
  {
    _customerService = customerService;
  }

  public void CreateOrder(Order order, int createdBy)
  {
     var customer = new Customer
        {
           FirstName = order.FirstName,
           LastName = order.FirstName //intentional bug
        };
    _customerService.Save(customer, createdBy);

    //TODO: do some other stuff with the order.
  }
}

In a test, let’s just use Moq’s Verify method and you’ll see what I mean about clear failure messages:

[Test]
public void WhenCreatingAnOrderSaveTheCustomerDetails()
{
  const int orderCreatedByPersonId = 1;

  var customerServiceMock = new Mock<ICustomerService>();

  var orderService = new OrderService(customerServiceMock.Object);
  orderService.CreateOrder(new Order { FirstName = "John", LastName = "Smith", OrderItems = new List<OrderItem>() }, orderCreatedByPersonId);

  customerServiceMock.Verify(x => x.Save(It.Is<Customer>(y => y.FirstName == "John" && y.LastName == "Smith"), orderCreatedByPersonId));
}

And this is the error you’ll see:

Moq.MockException :
Expected invocation on the mock at least once, but was never performed: x => x.Save(It.Is<Customer>(y => y.FirstName == "John" && y.LastName == "Smith"), 1)
No setups configured.

Performed invocations:
ICustomerService.Save(Customer, 1)

I don’t like this error message. You can’t tell what caused the failure. You can see that ICustomerService.Save was called with a Customer object (and the number 1), bit you can’t see why the test failed.

You could split up the Verify – use two verify calls to help pinpoint where it has failed:

[Test]
public void WhenCreatingAnOrderSaveTheCustomerDetails_SplitVerify()
{
  const int orderCreatedByPersonId = 1;

  var customerServiceMock = new Mock<ICustomerService>();

  var orderService = new OrderService(customerServiceMock.Object);
  orderService.CreateOrder(new Order { FirstName = "John", LastName = "Smith", OrderItems = new List<OrderItem>() }, orderCreatedByPersonId);

  customerServiceMock.Verify(x => x.Save(It.Is<Customer>(y => y.FirstName == "John"), orderCreatedByPersonId));
  customerServiceMock.Verify(x => x.Save(It.Is<Customer>(y => y.LastName == "Smith"), orderCreatedByPersonId));
}

And this is the error you’ll see. It is a lot better as you now know exactly which part of the verify call failed (i.e. the last name of the customer).

Moq.MockException :
Expected invocation on the mock at least once, but was never performed: x => x.Save(It.Is<Customer>(y => y.LastName == "Smith"), 1)
No setups configured.

Performed invocations:
ICustomerService.Save(Recommendations.Customer, 1)

Now let’s use callbacks instead t give you a much more obvious error message. In your arrange part of the test, you set up a callback to catch the data sent to the mocked dependency:

[Test]
public void WhenCreatingAnOrderSaveTheCustomerDetails_UsingCallbacks()
{
  const int orderCreatedByPersonId = 1;

  var customerServiceMock = new Mock<ICustomerService>();
  Customer actualCustomer = null;
  int actualSavedBy=0;
  customerServiceMock.Setup(x => x.Save(It.IsAny<Customer>(), It.IsAny<int>())).Callback<Customer,int>((customer, person) =>
                              {
                               actualCustomer = customer;
                               actualSavedBy = person;
                              }); //set up the callback to catch the parameters sent to Save()

  var orderService = new OrderService(customerServiceMock.Object);
  orderService.CreateOrder(new Order { FirstName = "John", LastName = "Smith", OrderItems = new List<OrderItem>()},orderCreatedByPersonId);

  actualSavedBy.Should().Be(orderCreatedByPersonId);
  actualCustomer.Should().NotBeNull();
  actualCustomer.FirstName.Should().Be("John");
  actualCustomer.LastName.Should().Be("Smith");
}

Now you’ll see a much nicer error message (from Fluent Assertions):

Expected string to be "Smith", but "John" is too short.

Posted in .NET, Moq, Test Driven Development | Tagged: , , | 1 Comment »

How much TDD is enough TDD?

Posted by Kash Farooq on June 14, 2013

[We had a discussion at my current client about the right-level of TDD for a project under tight deadlines. This post is adapted from my contribution to that discussion]

I’ll start by stating that I am a huge fan of Test Driven Development.

I was introduced to TDD in 2005, “got it” straight away and now, 8 years later, would not want to program without it.

I’m not going to go into the benefits of TDD in this post. There are plenty of other blog posts out there that discuss that. Basically, as I said, I’m a fan – I’ve seen how easy it is to make changes to a well crafted TDD project and I would recommend TDD as a programming and design methodology to anyone that will listen.

However…would I aim for 100% code coverage on a project? I’m not sure. You have to be pragmatic. When you have project specific time constraints, you have to look at the value that each unit test is adding. 

Consider a really light MVC controller action:

  1. Call a service.
  2. Use AutoMapper to map the response from a service contract to an identical view model.
  3. Return a View.

You may have dozens of controller actions like this. And for experienced developers, this three line method probably doesn’t need a unit test.  There is no functionality to be described by the unit test. Your unit test is not adding any value. It is probably just going to replicate the implementation (and take more lines of code to do that replication). The test isn’t going to catch any accidentally introduced bugs as… well… it would be hard to introduce a bug without breaking it completely. And if you are changing a controller action, you’re going to hit it manually before you commit your change to source control, right?

Having said this, you also have to consider the skill and experience level of the team.

If I was mentoring someone new to TDD, or new to doing C# “properly”, I’d want them to do it 100% TDD. They shouldn’t write a line of production code without first writing the test. I would expect to see a unit test for that controller action example above.

But if your team is experienced, with developers who know how to do TDD, a test for the above method is probably overkill.

Forcing TDD on a novice developer has other benefits – it’s not just about teaching them how to do TDD. It forces developers to keep their classes small and targeted. Experienced developers should know all about SOLID. They shouldn’t need TDD to force their code to be clean and their classes to be targeted. It should be second nature.

So, when should an experienced developer do TDD?

How about if your MVC controller action was a bit fatter:

  1. Call a service.
  2. Get some data from it and call another service with that data.
  3. Conditionally manipulate/merge the data into one view model.
  4. Return a view dependent on what the model looks like.

Now, ignoring that this controller action may be doing too much, you definitely need to do this work TDD. There is sufficient logic that could be buggy, or could become buggy. Also, if your controller started as a simple 3 liner, but is starting to do more – now you do need to add a test.

Other example situations:

  • Is the code going to re-used? If so, do it TDD.
  • Is there functionality that needs documenting? A unit test with a suitable name can describe what functionality is being implemented  – it provides accurate documentation rather than comments or documents that seem to be out of date a few days after they were written. And, obviously, you have a unit test ensuring that the functionality is working.

So, the “do I need to do TDD” questions could be:

  • Is there sufficient logic that I will need to write that could be buggy? Do you have an if statement, or a loop or some other logic?
  • Is this code going to be re-used?
  • Is this code an API?
  • Is it not obvious what the code is doing?
  • Do you want to explain some functionality, or business rule, to a developer that might be looking at this code in the future?

If the answer to any of these questions is “yes”, you probably need to write a test first.

If the answer is “no”, and your code is as simple as the controller action example I gave at the start…you probably don’t need a test. But: you should have some UI-based integration tests (e.g. using something like Selenium Webdriver/Coypu) that get run by your Continuous Integration solution to make sure the system hangs together after each commit.

However…

These aren’t hard and fast rules. There are other factors to take into consideration.

Is the team a a mixture of experienced and novice developers? Well, you can’t have one rule for one, and one for the another! Especially if everyone is going to work on all parts of the system.

Is the code going to be handed over to another team? Then you’d better do it TDD.

Perhaps these two scenarios mean you will always need to write tests for everything and my whole post is pointless!

Related posts

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

How to force SQL Server to drop DB connections

Posted by Kash Farooq on February 20, 2013

I keep on needing this script so I thought I’d post it here.

Use Master
Go

Declare @dbname sysname
Set @dbname = '<YOUR DATABASE NAME>'

Declare @spid int
Select @spid = min(spid) from master.dbo.sysprocesses
where dbid = db_id(@dbname)

While @spid Is Not Null
 Begin
 Execute ('Kill ' + @spid)
 Select @spid = min(spid) from master.dbo.sysprocesses
 where dbid = db_id(@dbname) and spid > @spid
 End

Posted in Uncategorized | Tagged: | Leave a Comment »

AutoMapper: Mapping nested complex types

Posted by Kash Farooq on August 20, 2012

Some production code I was working on  wasn’t working as expected, so I thought I’d spike it out.

AutoMapper allows you to map between, say, a service layer and a DTO without you having to write hardly any code. Install it with NuGet.

Here is an example. I have some types in my service layer:


namespace Automapper.Spike.Example1.Contract
{
  public class CreateOrderRequest
  {
    public int Id { get; set; }
    public int NumberOfItems { get; set; }
    public Customer Customer { get; set; }
  }

  public class Customer
  {
    public int Id { get; set; }
    public string FullName { get; set; }
    public string Postcode { get; set; }
   }
}

I want to map these to a DTO layer for storage:


namespace Automapper.Spike.Example1.Dto
{
  public class Order
  {
    public int Id { get; set; }
    public int NumberOfItems { get; set; }
    public Customer Customer { get; set; }
  }

  public class Customer
  {
    public int Id { get; set; }
    public string Name { get; set; }
    public string Postcode { get; set; }
  }
}

I just need to tell AutoMapper that I want it to map between these types:


public class MapperConfiguration
{
  public void Configure()
  {
    Mapper.CreateMap<Customer, Dto.Customer>()
      .ForMember(x=>x.Name,o=>o.MapFrom(src=>src.FullName));
    Mapper.CreateMap<CreateOrderRequest, Dto.Order>();
  }
}

That’s all the code you need. If FullName was just called Name, I wouldn’t even need the extra ForMember line.

Here is a test to check it all works:


[TestFixture]
public class Example1Test
{
  [Test]
  public void CheckMappings()
  {
    new MapperConfiguration().Configure();
    try
    {
      Mapper.AssertConfigurationIsValid();
    }
    catch (Exception e)
    {
      Console.WriteLine(e);
      Console.WriteLine(e.InnerException);
      throw;
    }

    var createOrderRequest = CreateTestOrderRequest();
    var order = Mapper.Map<Order>(createOrderRequest);

    order.Customer.Should().NotBeNull();
    order.Customer.Id.Should().Be(3);
    order.Customer.Name.Should().Be("Bob Smith");
    order.Customer.Postcode.Should().Be("W1 1AA");
    order.Id.Should().Be(1);
    order.NumberOfItems.Should().Be(2);
  }

  private static CreateOrderRequest CreateTestOrderRequest()
  {
    return new CreateOrderRequest
    {
      Id = 1,
      NumberOfItems = 2,
      Customer = new Customer
      {
        Id = 3,
        FullName = "Bob Smith",
        Postcode = "W1 1AA"
      }
    };
  }
}

Note the Mapper.AssertConfigurationIsValid() method. When you call this, AutoMapper will check you have provided enough configuration info.

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

Creating dynamic objects from JSON in .NET 4

Posted by Kash Farooq on July 23, 2012

I’m seeing quite a lot of people arriving at this blog with searches such as “datacontractjsonserializer .net 4”.

They end up at one of my old posts: Creating .NET objects from JSON using DataContractJsonSerializer. Implementing this will work in .NET 4, but why would you want to use DataContractJsonSerializer when you can use .NET 4 dynamic objects instead?

So, here is a very short blog post describing how to do just that.

I’m using some JSON I got from the Rotten Tomatoes API (which is excellent by the way). The JSON is all in one line so click hover over it and click the View Source icon to see it in a scrollable pop-up window.

{"id":11292,"title":"Star Wars: Episode IV - A New Hope","year":1977,"genres":["Action & Adventure","Mystery & Suspense","Science Fiction & Fantasy"],"mpaa_rating":"PG","runtime":105,"critics_consensus":"A legendarily expansive and ambitious start to the sci-fi saga, George Lucas opened our eyes to the possiblites of blockbuster filmmaking and things have never been the same.","release_dates":{"theater":"1977-05-25","dvd":"2004-09-21"},"ratings":{"critics_rating":"Certified Fresh","critics_score":94,"audience_rating":"Upright","audience_score":93},"synopsis":"","posters":{"thumbnail":"http://content9.flixster.com/movie/10/94/47/10944715_mob.jpg","profile":"http://content9.flixster.com/movie/10/94/47/10944715_pro.jpg","detailed":"http://content9.flixster.com/movie/10/94/47/10944715_det.jpg","original":"http://content9.flixster.com/movie/10/94/47/10944715_ori.jpg"},"abridged_cast":[{"name":"Mark Hamill","id":"162665747","characters":["Luke Skywalker"]},{"name":"Harrison Ford","id":"162661579","characters":["Han Solo"]},{"name":"Carrie Fisher","id":"162663355","characters":["Princess Leia Organa"]},{"name":"Peter Cushing","id":"162658723","characters":["Grand Moff Tarkin"]},{"name":"Alec Guinness","id":"162655900","characters":["Ben Obi-Wan Kenobi"]}],"abridged_directors":[{"name":"George Lucas"}],"studio":"20th Century Fox","alternate_ids":{"imdb":"0076759"},"links":{"self":"http://api.rottentomatoes.com/api/public/v1.0/movies/11292.json","alternate":"http://www.rottentomatoes.com/m/star_wars/","cast":"http://api.rottentomatoes.com/api/public/v1.0/movies/11292/cast.json","clips":"http://api.rottentomatoes.com/api/public/v1.0/movies/11292/clips.json","reviews":"http://api.rottentomatoes.com/api/public/v1.0/movies/11292/reviews.json","similar":"http://api.rottentomatoes.com/api/public/v1.0/movies/11292/similar.json"}}

I have put the above JSON into a text file which I’ll access via a test:

[Test]
public void DeserializeJsonWithDynamic()
{
  string starWarsAsJson = File.ReadAllText(@"DataGateways\RottenTomatoes\StarWars.json");
  dynamic starWarsAsDynamic = Json.Decode(starWarsAsJson);
  Console.WriteLine("Title: "+starWarsAsDynamic.Title);
  Console.WriteLine("Year: " + starWarsAsDynamic.Year);
  Console.WriteLine("Original Poster: " + starWarsAsDynamic.Posters.Original);
}

In the above code I’m using Json.Decode, which is in System.Web.Helpers, to create a dynamic object out of the JSON text.

Running the test results in the following output:

Title: Star Wars: Episode IV - A New Hope
Year: 1977
Original Poster: http://content9.flixster.com/movie/10/94/47/10944715_ori.jpg

Very cool. Notice I went down the JSON object hierarchy to get Posters.Original.

Posted in .NET | Tagged: , , , | 2 Comments »

Creating a database schema with Fluent NHibernate

Posted by Kash Farooq on July 17, 2012

If you create your model in C# first, and then want to create a database schema that matches that model, you can do this easily with Fluent NHibernate.

First, you need some sort of Data Access Initialization class.

public class DataAccessInitializer
{
  private static ISessionFactory sessionFactory;
  private readonly FluentConfiguration fluentConfiguration;
  private Configuration nhibernateConfiguration;

  public DataAccessInitializer()
  {
    //Fluently configure nHibernate and save the nHibernate config that has been created by Fluent
    fluentConfiguration = CreateFluentConfiguration().ExposeConfiguration(cfg => nhibernateConfiguration = cfg);
  }

  public Configuration NhibernateConfiguration
  {
    get { return nhibernateConfiguration; }
  }

  public ISessionFactory CreateSessionFactory()
  {
    return sessionFactory ?? (sessionFactory = fluentConfiguration.BuildSessionFactory());
  }

  private static FluentConfiguration CreateFluentConfiguration()
  {
    var entitiesToMapConfiguration = new EntitiesToMapConfiguration();
    return Fluently.Configure()
        .Database(MsSqlConfiguration.MsSql2008
                        .ConnectionString(x => x.Server(".")
                        .Database("nHibernateAndWebSessionManagement")
                        .TrustedConnection()))
        .Mappings(m => m.AutoMappings.Add(AutoMap.AssemblyOf<Movie>(entitiesToMapConfiguration))); //Movie is one of my entities that needs mapping
  }

  //Class to limit the objects Fluent is interested in
  private class EntitiesToMapConfiguration : DefaultAutomappingConfiguration
  {
    public override bool ShouldMap(Type type)
    {
      return type.Namespace == "MovieSearch.DataAccess.Entities"; //only use classes in this namespace.
    }
  }
}

You could use this to create your Session Factory for any app. Note that I’ve created a EntitiesToMapConfiguration class to limit the types that Fluent is interested in. I don’t want NHibernate to start looking for a DataAccessInitializer table.

I’ve done one extra thing that you don’t need if you just want to create sessions from the Session Factory: I’ve called FluentConfiguration.ExposeConfiguration to save the NhibernateConfiguration into a private variable. I have also created a public NhibernateConfiguration property that exposes this so that it can specifically be used by the following code to create the database schema:


[TestFixture]
public class DataAccessTest
{
  private static void BuildSchema(Configuration cfg)
  {
    new SchemaUpdate(cfg).Execute(true, true);
  }

  [Test]
  [Explicit]
  public void CreateSchema()
  {
    var dataAccessService = new DataAccessInitializer();
    dataAccessService.CreateSessionFactory();
    BuildSchema(dataAccessService.NhibernateConfiguration);
  }
}

I’ve wrapped the runner in an NUnit test, and used the ExplicitAttribute to prevent the test from running accidentally – it won’t run if you chose to run all tests in a solution, only if you run that one test explicitly.

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

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;
  }
}

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 »

 
Follow

Get every new post delivered to your Inbox.