Kash Farooq's software development blog

.NET Developer

Posts Tagged ‘TDD’

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 »

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 »

More TDD with wrapper classes

Posted by Kash Farooq on June 23, 2012

I have previously blogged about using wrapper classes to test the hard to test. In that post I made things easy for myself by using the parameterless constructor of the SmtpClient class.

I thought I’d revisit this area of testing, and try something different. This time I’ve used Moq rather than Rhino Mocks for starters. But I’m also going to pretend that SmtpClient does not have a parameterless constructor.  If a class you need to make testable does not have a parameterless constructor, it makes things a bit trickier:

public class SystemUnderTest
{
  public void MethodToBeTested()
  {
    var mailMessage = new MailMessage { Subject = "Hello", From = new MailAddress("Me@Me.com") };
    mailMessage.To.Add(new MailAddress("You@You.com"));
    var smtpClient = new SmtpClient("smtp.kashfarooq.com", 25);
    smtpClient.Send(mailMessage);
  }
}

A number of things in the above code need to be addressed and tested. The SMTP client is being instantiated in the method with the host and port being sent in via a the constructor, which makes things awkward to test. Apart from that complication, I’d like to make sure the correct host and port are being used. And I’d also like to make sure the correct details are being set in the MailMessage object.

First, we need an interface so we can mock the Send method. This matches the SmtpClient.Send method exactly:

public interface ISmtpClient
{
  void Send(MailMessage mailMessage);
}

We also need a wrapper class that will wrap SmtpClient and the constructor we are planning to use:

public class SmtpClientWrapper : SmtpClient, ISmtpClient
{
  public SmtpClientWrapper(string host, int port) : base(host, port)  { }
}

The above wrapper class inherits the interface defined above and the class we are trying to make testable: SmtpClient. And as it derives from SmtpClient, it automatically implements ISmtpClient.Send(MailMessage).

Next, we’ll create a suitable constructor for our SystemUnderTest class so that we can inject in some mocks. Because the MethodToBeTested creates the SmtpClient object, I’m going to use the “Using a Func instead of a Factory” trick:

private readonly Func<string, int, ISmtpClient> createSmtpClient;

public SystemUnderTest(Func<string, int, ISmtpClient> createSmtpClient)
{
  this.createSmtpClient = createSmtpClient;
}

public SystemUnderTest() : this((host,port) => new SmtpClientWrapper(host, port)) {}

So, what’s going on here? I have created a Func that will take a string and int (the host and port) and return an ISmtpClient. From my test I’ll use the first constructor. The production code will use the second constructor. In both cases, the Func supplied is stored in createSmtpClient – and this will be called from MethodToBeTested to actually create the SmtpClient.

I’m now in full control of all the dependencies. I can catch the MailMessage parameter sent to the Send method, and the host and port name sent to the createSmtpClient Func, which ultimately gets sent to to the SmtpClient(string host, int port) constructor.

And here is the test that creates a mock ISmtpClient and a Func that returns it, and also catches the parameters sent to it so the appropriate asserts can be done:

[Test]
public void CorrectEmailSentViaTheCorrectSmtpHost()
{
  string actualHostName=string.Empty;
  int actualPort=0;
  MailMessage actualMailMessage = null;

  var mockSmtpClient = new Mock<ISmtpClient>();
  mockSmtpClient
     .Setup(x => x.Send(It.IsAny<MailMessage>()))
     .Callback((MailMessage message) => actualMailMessage = message); //Catch the MailMessage sent to the Send method

  //Func to return an ISmtpClient and catch data sent to it
  Func<string, int, ISmtpClient> createSmtpClient = (host, port) =>
      {
         actualHostName = host; //catch the hostname used
         actualPort = port; //catch the port used
         return mockSmtpClient.Object; //return mocked SmtpClient
  };

  //Call system under test
  var sut = new SystemUnderTest(createSmtpClient);
  sut.MethodToBeTested();

  //Asserts
  actualHostName.Should().Be("smtp.kashfarooq.com");
  actualPort.Should().Be(25);
  actualMailMessage.Subject.Should().Be("Hello");
  actualMailMessage.From.Address.Should().Be("Me@Me.com");
  actualMailMessage.To[0].Address.Should().Be("You@You.com");
}

[Incidentally, I’m using the excellent FluentAssertions in my asserts.]

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

How to test DateTime.Now

Posted by Kash Farooq on June 17, 2012

A colleague new to TDD asked me how to do this recently, so I thought I’d blog it.

Here is some code we want to bring under test:

public void SomeMethodToBeTested()
{
  var dateTimeNow = DateTime.Now;
  if (dateTimeNow.Month == 4 && dateTimeNow.Day == 6)
  {
    //do something for the new tax year.
  }
  else
  {
    //do something for the current tax year.
  }
}

The problem is: how can we test different dates so make sure the correct tax year dependent processing takes place? We clearly need the ability to control the date being used. We could do this by creating a wrapper class for DateTime, but I prefer in this simple case to just use a Func.

The test code becomes:

[TestFixture]
public class StubbingDateTimeNowTest
{
  [Test]
  public void TestNewTaxTear()
  {
    var stubbingDateTimeNow=new StubbingDateTimeNow(() => new DateTime(2012,4,6)); //send in a Func to return the date I want to test
    stubbingDateTimeNow.SomeMethodNowTested();
    //Asserts to check correct processing took place
  }

  [Test]
  public void TestCurrentTaxTear()
  {
    var stubbingDateTimeNow=new StubbingDateTimeNow(() => new DateTime(2012,3,6)); //send in a Func to return the date I want to test
    stubbingDateTimeNow.SomeMethodNowTested();
    //Asserts to check correct processing took place
  }
}

And the code under test needs a constructor to enable me to inject in the Func that creates a DateTime object. The default constructor that would be called in production simply provides a Func that will return DateTime.Now when called:

public class StubbingDateTimeNow
{
  private readonly Func<DateTime> getCurrentDateTime;

  public StubbingDateTimeNow(Func<DateTime> getCurrentDateTime)
  {
    this.getCurrentDateTime = getCurrentDateTime;
  }

  public StubbingDateTimeNow() : this(() => DateTime.Now) {} //default constructor provides a Func to return DateTime.Now

  public void SomeMethodNowTested()
  {
     var dateTimeNow = getCurrentDateTime();
     if (dateTimeNow.Month == 4 && dateTimeNow.Day == 6)
     {
       //do something for the new tax year.
     }
     else
     {
       //do something for the current tax year.
     }
  }
}

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

Playing with FluentAssertions

Posted by Kash Farooq on February 23, 2012

I thought I’d try a FluentAssertions - a different way of doing asserts in Unit Tests.

As the name of the library suggests, your assertion code is fluent. i.e. methods are chained.

Some examples.

A simple assert:

person.YearOfBirth.Should().Be(1945);

To check a list has the correct number of elements:

personList.Should().HaveCount(10);

To ensure that a list has elements in a certain order:

IEnumerable<int> positions = personList.Select(x => x.Rank);
positions.Should().ContainInOrder(new[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10});

There are lots of helper methods and the lots of examples in the on-line documentation.

I quite like it and have been using it on a project.

And it’s not just the assertion style that I like.

The thing that really impressed me was when one of my tests failed. In my assert I was comparing two strings. I clearly should have done a .Trim() on my string under test, but I forgot. And here is the error I saw in my test runner window:


Expected string to be
"John Smith", but it has unexpected whitespace at the end.

How useful is that! No more “the string differs at position 45″.

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

BDD with SpecFlow and Coypu (Part 2)

Posted by Kash Farooq on August 23, 2011

In my last post I introduced BDD with SpecFlow. I created a  feature file and got to a point where I now needed to hook up my BDD tests with browser integration. To do this, I’m going to use Coypu and the Selenium headless browser. See my previous post for download links.

First, let’s configure Coypu to use the Selenium headless browser:

[Binding]
public class CoypuInitializer {
    [BeforeTestRun]
    public static void BeforeTestRun()
    {
        //I'm using the Dev Studio cassini server;
        Configuration.AppHost = "localhost";
        Configuration.Port = 64567;

        ConfigureForHeadlessBrowser();
    }

    private static void ConfigureForHeadlessBrowser()
    {
        Configuration.Driver = typeof(SeleniumHtmlUnitWebDriver);
    }

    [AfterScenario]
    public static void AfterScenario()
    {
        Coypu.Browser.EndSession();
    }
}

 

public class SeleniumHtmlUnitWebDriver : SeleniumWebDriver {
    public SeleniumHtmlUnitWebDriver() : base(new RemoteWebDriver(DesiredCapabilities.HtmlUnit())) {}
}

You will also need to add DLL references to Coypu.dll and WebDriver.dll (which is in the Coypu zip).

You can use this class to make other global configuration settings such as the Timeout, or the time Coypu waits between retries when looking for a HTML element. Full details can be found at the GitHub Coypu website, or the README.md file that comes with the Coypu binaries.

Now we are ready to implement the first feature step. As a reminder, the feature file is:

Scenario: Display Pi using Taylor series and Bucknall's BigNumber to many decimal places
	Given I visit the Pi.NET website
	And I have selected the 'Bucknall Big Number' algorithm
	And I have entered 500 decimal places
	When I press Go
	Then Pi should be displayed to the correct number of decimal places
	And Calculation statistics should be displayed

Let’s implement the “Given I visit the Pi.NET website” step:

[Given(@"I visit the Pi\.NET website")]
public void GivenIVisitThePiWebsite() {
    Browser.Session.Visit(string.Format("/"));
}

Using Coypu, I’m going to open the website specified in the CoypuInitializer class and visit the root of that website.

I now go to my MVC app and implement just enough to get that step passing.

Once I’ve done that, running the tests now gives:


Given I visit the Pi.NET website
-> done: PiNetSteps.GivenIVisitThePiWebsite() (15.4s)
And I have selected the 'Bucknall Big Number' algorithm
-> pending: PiNetSteps.GivenIHaveSelectedTheBucknallBigNumberAlgorithm("Bucknall Big Number")

i.e. – the first step has completed and the test has stopped at the next pending step. We’ve successfully hit the website.

I proceed like this, step by step, until I end up with the following steps file. I’ve added comments to explain the Coypu features I am using:

[Binding]
public class PiNetSteps:Steps {
    private string numberOfDecimalPlaces;

    [Given(@"I have selected the '(.+)' algorithm")]
    public void GivenIHaveSelectedAnAlgorithm(string algorithm) {
        //pass on this call to the generic radio button method (later in this class)
        Given(string.Format("I select the radio button '{0}'", algorithm));
    }

    [Given(@"I have entered (.+) decimal places")]
    public void GivenIHaveEnteredTheNumberOfRequiredDecimalPlaces(string numberOfDecimalPlaces) {
        this.numberOfDecimalPlaces = numberOfDecimalPlaces; //store for later use in an assert
        //populate a text box
        Browser.Session.FillIn("NumberOfDecimalPlaces").With(numberOfDecimalPlaces);
    }

    [When(@"I press Go")]
    public void WhenIPressGo() {
        //click a link. This fires an AJAX post to controller action
        //(I wanted to test JS capabilities of Selenium headless browser)
        Browser.Session.ClickLink("Calculate");
    }

    [Then(@"Pi should be displayed to the correct number of decimal places")]
    public void ThenPiShouldBeDisplayedToTheRequestedNumberOfDecimalPlaces() {
        //Check page HasContent I'm after - "Number of iterations" is displayed by AJAX call result
        if (Browser.Session.HasContent("Number of iterations:")) {
            //check Pi is calculated to correct number of places
            string piToNumberOfRequiredDecimalPlaces = Pi.Get(Convert.ToInt32(numberOfDecimalPlaces));
            Element piElement = Browser.Session.FindField("pi"); //find HTML element
            string calculatedPi = piElement.Text;
            Assert.That(piToNumberOfRequiredDecimalPlaces, Is.EqualTo(calculatedPi));
        }
        else {
            Assert.Fail("Could not find PI");
        }
    }

    [Then(@"Calculation statistics should be displayed")]
    public void ThenCalculationStatisticsShouldBeDisplayed() {
        //you can use actions/funcs with different retry timeouts
        Assert.IsTrue(Browser.Session.WithIndividualTimeout(TimeSpan.FromMilliseconds(1),
                       () => Browser.Session.HasContent("Number of iterations: ")),
                       "Number of Iterations taken not found");
        Assert.IsTrue(Browser.Session.WithIndividualTimeout(TimeSpan.FromMilliseconds(1),
                       () => Browser.Session.HasContent("Number of decimal places: " + numberOfDecimalPlaces)),
                       "Number of Decimal places calculated not found");
        Assert.IsTrue(Browser.Session.WithIndividualTimeout(TimeSpan.FromMilliseconds(1),
                       () => Browser.Session.HasContent("Elapsed Milliseconds: ")),
                       "Time taken not found");
    }

    [Given(@"I select the radio button '(.+)'")]
    public void SelectARadioButton(string radioButtonValue) {
        //select a radio button by value
        Browser.Session.Choose(radioButtonValue);
    }

    [Given(@"I visit the Pi.NET website")]
    public void GivenIVisitThePiPage() {
        //visit a web page at site specified in Coypu initialization.
        Browser.Session.Visit(string.Format("/"));
    }
}

I’ve used several SpecFlow and Coypu features in the class above. There are many more that you can read about at the GitHub Coypu website, or the README.md file that comes with the Coypu binaries. The documentation also shows how to use a real browser, rather than the Selenium headless one.

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

BDD with SpecFlow and Coypu (Part 1)

Posted by Kash Farooq on August 19, 2011

I’ve been doing TDD for years and I thought it was about time I got into BDD too.

I’m going to use BDD to add a UI in front of the various implementations of Pi calculation algorithms I’ve been working on.

This post will describe what you need to install and how to get a SpecFlow feature file running via NUnit.

Prerequisites

Headless browser:

Firing up a real browser from a BDD test can be slow. So, I’m using the Selenium headless Java browser.

Download selenium-server-standalone-2.4.0.jar (and, of course, you need Java)

To start it up:


java -jar selenium-server-standalone-2.3.0.jar

SpecFlow:

Install SpecFlow with the full installer and it will integrate with Dev Studio.

You can keep your feature files in your solution and SpecFlow will automatically generate NUnit based code-behind files.

I also recommend you watch the SpecFlow Screen Cast – an excellent introduction to quickly get you up and running.

Coypu

To get my SpecFlow BDD tests to interact with the browser, I’m using Coypu.

Coypu is:

A more intuitive DSL for interacting with the browser in the way a human being would, inspired by the ruby framework Capybara.

Other software

You need NUnit (as SpecFlow creates NUnit tests).

Adding the first feature file

I’ve already got a few implementations of algorithms to calculate Pi. I just want a simple UI that allows you to select an algorithm, type how many decimal places you want Pi calculated to, and then hit “Calculate”. I want the “Calculate” link/button to call back to my application via AJAX (I want to see how the headless browser copes with Javascript).

Step 1: Add a feature file

A feature file is just a text file that describes the functionality you want to implement. It has a simple Given-When-Then structure that should be understandable by non-developers. Hence, they could be created by Business Analysts, etc.

I created a new class library called Spec and added a feature file using the “Add New Item” Dev Studio menu. You’ll see the option “SpecFlow Feature File”.

Feature: Calculate Pi using various algorithms
	I want to be able to view Pi to varying decimal places

Scenario: Display Pi using Taylor series and Bucknall's BigNumber to many decimal places
	Given I visit the Pi.NET website
	And I have selected the 'Bucknall Big Number' algorithm
	And I have entered 500 decimal places
	When I press Go
	Then Pi should be displayed to the correct number of decimal places
	And Calculation statistics should be displayed

You’ll also need to add DLL references to TechTalk.SpecFlow.dll and nunit.framework.dll

Once you’ve done this, compile and run all the unit tests in your Spec class library. You’ll see output like this:


Given I visit the Pi.NET website
-> No matching step definition found for the step. Use the following code to create one:
[Binding]
public class StepDefinitions {
   [Given(@"I visit the Pi\.NET website")]
   public void GivenIVisitThePi_NETWebsite()
   {
       ScenarioContext.Current.Pending();
   }
}
etc, etc.

SpecFlow has told you exactly what you need to do.

So, let’s copy and paste the code into a new C# file called PiNetSteps:

[Binding]
public class PiNetSteps {
    [Given(@"I visit the Pi\.NET website")]
    public void GivenIVisitThePi_NETWebsite() {
        ScenarioContext.Current.Pending();
    }

    [Given(@"I have selected the 'Bucknall Big Number' algorithm")]
    public void GivenIHaveSelectedTheBucknallBigNumberAlgorithm() {
        ScenarioContext.Current.Pending();
    }

    [Given(@"I have entered 500 decimal places")]
    public void GivenIHaveEntered500DecimalPlaces() {
        ScenarioContext.Current.Pending();
    }

    [When(@"I press Go")]
    public void WhenIPressGo() {
        ScenarioContext.Current.Pending();
    }

    [Then(@"Pi should be displayed to the correct number of decimal places")]
    public void ThenPiShouldBeDisplayedToTheCorrectNumberOfDecimalPlaces() {
        ScenarioContext.Current.Pending();
    }

    [Then(@"Calculation statistics should be displayed")]
    public void ThenCalculationStatisticsShouldBeDisplayed() {
        ScenarioContext.Current.Pending();
    }
}

Now when you run the unit tests you get the output:


Ignored: One or more step definitions are not implemented yet.

We can improve the steps code by parameterizing it with Regex. For example, rather than hard coding “500 decimal places”, let’s make this a parameter. And the algorithm name can also be a parameter.

Making these changes gives:

[Given(@"I have selected the '(.+)' algorithm")]
public void GivenIHaveSelectedAnAlgorithm(string algorithm) {
    ScenarioContext.Current.Pending();
}

[Given(@"I have entered '(.+)' decimal places")]
public void GivenIHaveEnteredTheRequiredNumberOfDecimalPlaces(int numberOfDecimalPlaces) {
    this.numberOfDecimalPlaces = numberOfDecimalPlaces; //store for a later assert
    ScenarioContext.Current.Pending();
}

We’re now at a stage that opens up lots of possibilities. You’ve gone from a feature file to a C# class and you now have options on how deep you want your tests to go. If you system under test is not a web application, you are ready to start implementing it straight away. If your system has lots of external dependencies that are not under your control, you could easily stub them out with a container. Or perhaps you want your tests to go through all the application layers and hit a database or webservice. You could easily introduce test database and webservices if you wish.

In the next post I’ll get Coypu up and running and use it to get my SpecFlow steps class to hit the Selenium headless browser.

Next: BDD with SpecFlow and Coypu (Part 2)

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

 
Follow

Get every new post delivered to your Inbox.