Kash Farooq's software development blog

.NET Developer

Archive for the ‘Test Driven Development’ Category

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 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 »

Unit Testing with SQL Lite and Fluent NHibernate

Posted by Kash Farooq on January 2, 2011

I used to unit test NHibernate criteria by, essentially, interaction testing.

It’s fairly straight forward to do this (NHibernate provides lots of interfaces that are easy to mock), but the test code ends up just mirroring the production code. Your test would check that CreateCriteria was called, then an Expression was added, then List was called, etc, etc.

If the production code changes (for example, a more efficient criteria is implemented, or HQL is used), the test would need to be completely rewritten. This defeats one of the objectives of TDD – provide an environment in which refactoring can be done safely, with the confidence that the new code does exactly what the old code did.

So, I switched to using SQL Lite to allow my unit tests to actually hit an in-memory database. I think this is perfectly acceptable for simple queries that are not using any DB specific features. The tests are also fast enough to run on a Continuous Build server.

The code in this post uses Fluent NHibernate to configure NHibernate. It allows me to easily configure my production code to use a SQL Lite database via my test code, and to use a production database via my production code.

Let’s start with a very simple Model – the data to be persisted.

namespace SystemUnderTest.Model {
  public class Person {
    public virtual long Id { get; set; }
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }
    public virtual DateTime DateOfBirth { get; set; }
  }
}

Next, we need some code that configures NHibernate using Fluent, and allows me to set the database type to use. Note that the code exposes the Session Factory so I can create a session when needed. It also exposes the NHibernate configuration. I will use this from the unit test to create a schema inside my SQL Lite in-memory database.

namespace SystemUnderTest.DataAccess {
  public class DataSession {
    private readonly IPersistenceConfigurer _dbType;
    public DataSession(IPersistenceConfigurer dbType) {
      _dbType = dbType;
      CreateSessionFactory();
    }

    private ISessionFactory _sessionFactory;
    private Configuration _configuration;

    public ISessionFactory SessionFactory {
      get { return _sessionFactory; }
    }

    public Configuration Configuration {
      get { return _configuration; }
    }

    private void CreateSessionFactory() {
      _sessionFactory = Fluently
      .Configure()
      .Database(_dbType)
      //Only map classes in the Assembly of 'Person' that have a namespace ending in .Model
      .Mappings(m => m.AutoMappings.Add(
         AutoMap.AssemblyOf<Person>().Where(type => type.Namespace.EndsWith(".Model"))))
      .ExposeConfiguration(cfg => _configuration = cfg)
      .BuildSessionFactory();
    }
  }
}

Now, let’s look at a unit test. I will be creating a PersonRepository to save objects, query objects, etc. The test setup for this class needs to tell the production code ‘DataSession’ class to use an in-memory SQL Lite instance, and to build a schema inside this instance based on the configuration created by Fluent NHibernate.

[TestFixture]
public class PersonRepositoryTest {
 private DataSession _dataSession;
 private ISession _session;

 [TestFixtureSetUp]
 public void TestFixtureSetUp() {
    //Use In Memory database, open session and Build Schema inside In Memory database
    _dataSession = new DataSession(SQLiteConfiguration.Standard.InMemory());
    _session = _dataSession.SessionFactory.OpenSession();
    BuildSchema(_session, _dataSession.Configuration);
 }

 public void BuildSchema(ISession session, Configuration configuration) {
   var export = new SchemaExport(configuration);
   export.Execute(true, true, false, session.Connection, null);
 }

 [TestFixtureTearDown]
 public void TestFixtureTearDown() {
   //Clean up after tests have run
   _session.Close();
   _dataSession.SessionFactory.Close();
 }

 [SetUp]
 public void SetUp() {
   CleanTheTables(); //Make sure tables are empty before each test runs
 }
}

Now, a simple test to begin with. Create a person, save it using our PersonRepository class and then make sure we can find it inside the in-memory database.


[Test]
public void SaveAPersonTest() {
  var personRepository = new PersonRepository(_session);
  personRepository.Save(
     new Person{DateOfBirth = new DateTime(1970,1,1),FirstName = "John",LastName = "Smith"});

  //Now get all Person objects from DB and make sure our object has been persisted
  IList<Person> people = _session.CreateCriteria<Person>().List<Person>();
  Assert.That(people.Count,Is.EqualTo(1));
  Assert.That(people[0].FirstName,Is.EqualTo("John"));
}

Simple.

Now for something a little more complicated; something that we could implement using several methods (e.g. using Criteria, HQL, SQL).

[Test]
public void FindPeopleOlderThanCertainAgeTest() {
  var personRepository = new PersonRepository(_session);
  SaveFourPeopleWithTwoOlderThan30(personRepository);

  //Use repository to find people older than 30
  IList<Person> peopleOlderThan30 = personRepository.GetAllPeopleOlderThan(30);
  Assert.That(peopleOlderThan30.Count,Is.EqualTo(2));
  Assert.That(peopleOlderThan30.Count(x=>x.FirstName=="John")==1);
  Assert.That(peopleOlderThan30.Count(x=>x.FirstName=="Bob")==1);
}

This test provides our TDD safeguard. We can implement GetAllPeopleOlderThan any way we like and this test will ensure that it has been implemented correctly. We can refactor the production code at a later date and the test will ensure we haven’t introduced a bug.

For completeness, here is my implemented repository class:

public class PersonRepository {
  private readonly ISession _session;
  public PersonRepository(ISession session) {
    _session = session;
  }

  public void Save(Person person) {
    _session.Save(person);
  }

  public IList<Person> GetAllPeopleOlderThan(int ageInYears) {
    ICriteria criteria = _session.CreateCriteria<Person>();
    DateTime datePersonMustBeBornBefore = DateTime.Now.AddYears(-1*ageInYears);
    criteria.Add(Expression.Le("DateOfBirth", datePersonMustBeBornBefore));
    return criteria.List<Person>();
  }
}

Posted in Fluent NHIbernate, NHibernate, Test Driven Development | Tagged: , , | 1 Comment »

Rhino Mocks and AssertWasCalled MethodOptions

Posted by Kash Farooq on September 3, 2009

I always seem to struggle to find examples of how to use MethodOptions in Rhino Mocks, so here is some code.

Assume you have the following dependency:

public interface IDependency {
   void SomeMethod(int number);
   void SomeMethod(ComplexType complexType);
}

public class ComplexType {
   public string Name { get; set; }
}

And your system under test calls this dependency like this:

public class SystemUnderTest {
   private readonly IDependency dependency;
   public SystemUnderTest(IDependency dependency) {
      this.dependency = dependency;
   }

   public void DoSomething() {
       dependency.SomeMethod(9);
       dependency.SomeMethod(3);
   }

   public void DoSomethingElse() {
       dependency.SomeMethod(new ComplexType{Name = "London"});
   }
}

You can use MethodOptions to check that the dependency was called correctly.

First, let’s check that SomeMethod was called twice with integers greater than 1:

[Test]
public void EnsureDependencyCalledTwiceWithAnIntegerGreaterThanOne() {
  var dependency = MockRepository.GenerateStub<IDependency>();
  var systemUnderTest = new SystemUnderTest(dependency);
  systemUnderTest.DoSomething();

  dependency.AssertWasCalled(x => x.SomeMethod(0), 
                                                 options => 
                                                 {
                                                     options.Repeat.Twice();
                                                     options.Constraints(Is.GreaterThan(1));
                                                     options.Message("SomeMethod should have been called twice with integers greater than 1");
                                                 });
}

Next, let’s check that the correct ComplexType was sent to SomeMethod

[Test]
public void EnsureDependencyCalledWithCorrectComplexType() {
  var dependency = MockRepository.GenerateStub<IDependency>();

  var systemUnderTest = new SystemUnderTest(dependency);
  systemUnderTest.DoSomethingElse();

  Func<ComplexType, bool> checkArgs = arg => arg.Name == "London";
  //The above line can be written with an anonymous method instead:
  //Func<ComplexType, bool> checkArgs = delegate(ComplexType arg) { return arg.Name == "London"; };

  dependency.AssertWasCalled(x => x.SomeMethod(new ComplexType()), 
                                                        options => {
                                                           options.Callback(checkArgs);
                                                           options.Message("Name sent was not London");
                                                        });
}

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

TDD: Using an Action or a Func to test the hard to test

Posted by Kash Farooq on August 24, 2009

More uses for Actions (or Funcs).

Consider the code:

public class SystemUnderTest {
    public void SaveToFile(string data) {
    //
    //Some code
    //
    File.WriteAllText(@"myfile.txt",data);
    //
    //Some code
    //
  }
}

It writes to a file. We could create a unit test that lets the code write to file, then reads the file back in to make sure the file was created properly – but writing to the file system can hardly be considered a unit test.

So, what do we do? How do you test that the data you sent into SaveToFile is being written to a file with the correct filename.

You can pass in an Action. Let’s refactor the code:

public class SystemUnderTest {
  private readonly Action<string,string> writeAction;

  public SystemUnderTest (Action<string,string> writeAction) {
    this.writeAction = writeAction;
  }

  public SystemUnderTest ():this(File.WriteAllText) {}

  public void SaveToFile(string data) {
    //
    //Some code
    //
    writeAction(@"myfile.txt", data);
    //
    //Some code
    //
  }
}

In the constructor, I am passing in an Action that takes two string parameters corresponding to the signature of File.WriteAllText. In the default constructor I can set writeAction to the File.WriteAllText method.

Now, the corresponding test can be written as follows:

[Test]
public void EnsureDataSavedToCorrectFile() {
  string filenameUsed = "";
  string dataSentToFile = "";
  Action<string, string> writeAction = (filename, data) => {
                                                          filenameUsed = filename;
                                                          dataSentToFile = data;
                                                      };
  SystemUnderTest systemUnderTest = new SystemUnderTest(writeAction);
  systemUnderTest.SaveToFile("MyData");

  Assert.That(filenameUsed,Is.EqualTo("myfile.txt"));
  Assert.That(dataSentToFile,Is.EqualTo("MyData"));
}

This technique is similar to Using a Func instead of a Factory.
Note that the method I wanted to mock out returned void. If the method returned, say, bool, then I would need to use a Func rather than an Action.

Also, if you have a class that uses several of these hard to test methods, you will quickly end up with a very long parameter list for your constructor. You should consider introducing a parameter object.

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

TDD: Using a Func instead of a Factory

Posted by Kash Farooq on August 10, 2009

In this post I’ll look at using a Func to control object creation, which allows you to reduce the amount of code you need to write to make something testable.

Consider the following code:

public class SystemUnderTest {
  //A method that is currently impossible to test
  public void MyMethod() {
    using (var otherClass = new SomeOtherClass()) {
       if (!otherClass.DoWork()) {
          throw new ApplicationException("DoWork failed");
       }
     }
  }
}

SomeOtherClass looks like this:

public interface ISomeOtherClass : IDisposable {
  bool DoWork();
}

public class SomeOtherClass : ISomeOtherClass {
  public void Dispose() {}
  public bool DoWork() {
    return true;
  }
}

In it’s current state, SystemUnderTest cannot be tested. The SomeOtherClass object creation is happening inside the public method, so cannot be controlled from a unit test. We cannot test that if otherClass.DoWork returns false, an exception is thrown. We cannot test that otherClass.Dispose is called.

To make it possible to control the object creation from a test, we can introduce a factory class and interface and inject this into the SystemUnderTest:

public class SystemUnderTest {
  private readonly IFactory factory;
  public SystemUnderTest(IFactory factory) {
    this.factory = factory;
  }
	
//Default constructor creates the concrete Factory
  public SystemUnderTest():this(new Factory()) {}
	
  public void MyMethod() {
    using (var otherClass = factory.Create()) {
       if (!otherClass.DoWork()) {
          throw new ApplicationException("DoWork failed");
       }
    }
  }
}

//The interface we inject into SystemUnderTest to control the object creation:
public interface IFactory {
   ISomeOtherClass Create();
}

//The concrete implementation of IFactory just returns a new SomeOtherClass object:
public class Factory : IFactory {
  public ISomeOtherClass Create() {
    return new SomeOtherClass();
  }
}

Now, we can test this code:

[Test]
public void MyMethodThrowsExceptionIfDoWorkReturnsFalse() {
  //Mock a factory and set it up to return a mock SomeOtherClass object:
  var factory = MockRepository.GenerateStub();
  var someOtherClass = MockRepository.GenerateStub();
  factory.Expect(x => x.Create()).Return(someOtherClass);
  someOtherClass.Expect(x => x.DoWork()).Return(false);

  var systemUnderTest=new SystemUnderTest(factory);
	
  //Ensure that as DoWork returned false, an exception is thrown:
  try {
    systemUnderTest.MyMethod();
    Assert.Fail("Expected exception not thrown");
  }
  catch (ApplicationException) { }
	
  //Ensure dispose is always called:
  someOtherClass.AssertWasCalled(x => x.Dispose());
}

So, to write this test and to get SystemUnderTest working, we have had to introduce IFactory and a concrete implementation of Factory. That’s a lot of code to do something pretty simple.

We can do away with these two new code files if we use a Func to create the object:

public class SystemUnderTest {
  //A Func acting as a factory 
  private readonly Func<ISomeOtherClass> factory;

  public SystemUnderTest(Func<ISomeOtherClass> factory) {
    this.factory = factory;
  }
	
  //Default constructor creates the concrete SomeOtherClass object with a Func
  public SystemUnderTest():this(() => new SomeOtherClass()) {}
	
  public void MyMethod() {
    using (var someOtherClass=factory()) {
      if (!someOtherClass.DoWork()) {
          throw new ApplicationException("DoWork failed");
      }
    }
  }
}

I’ve still called the Func “Factory” to describe what it is doing – it is just creating an object.
The test now injects a Func to control the object creation:

[Test]
public void MyMethodThrowsExceptionIfDoWorkReturnsFalse() {
  var someOtherClass = MockRepository.GenerateStub();
  someOtherClass.Expect(x => x.DoWork()).Return(false);

  //Inject a func that returns my mock SomeOtherClass object:
  var systemUnderTest = new SystemUnderTest(() => someOtherClass); 
  try {
   systemUnderTest.MyMethod();
   Assert.Fail("Expected exception not thrown");
  }
  catch (ApplicationException) {}

  someOtherClass.AssertWasCalled(x => x.Dispose());
}

We have eliminated the need for the interface IFactory and the class Factory, and reduced the amount of mocking we had to do.

Posted in Test Driven Development | Tagged: , | 2 Comments »

Checking what was sent to a mock, readability of test code and readability of assert messages

Posted by Kash Farooq on August 7, 2009

There are several ways to determine what was sent to your mock object.
In this blog post I’ll look at using Rhino Mocks and Moq to test the same piece of code and check that the correct data was sent to a dependency. I’ll then also look at not bothering with a Mocking Framework, and just using a Fake instead.

If the method being called on the mock receives a simple type, it is easy to check that the correct data was sent to the mock. For example, with Rhino Mocks:

dependency.AssertWasCalled(m=>m.MyMethod(5));

However, things aren’t as simple if MyMethod receives a complex type.

For the examples below, here is the code under test. I have a dependency that receives a complex type:

//A complex type
public class PersonDetail {
   public string Name { get; set; }
   public string Address { get; set; }
}

//The dependency
public interface IPersonDetailsRepository {
   void StorePersonDetails(PersonDetail personDetail);
}

public class SystemUnderTest
{
    private readonly IPersonDetailsRepository repository;
    public SystemUnderTest(IPersonDetailsRepository repository) {
        this.repository = repository;
    }
}

public void CreatePerson(string name, string address) {
   //intentional bug (address and name the wrong way around) so that we can check the test failure messages
   repository.StorePersonDetails(new PersonDetail {Name = address, Address = name});
}

Rhino Mocks Matches syntax

With Rhino Mocks, one way to check the parameter sent to StorePersonDetails is to use the Matches syntax.

[Test]
public void CheckPersonDetailsAreSaved_RhinoMocks_ArgsMatches()
{
    const string personAddress = "London";
    const string personName = "John Smith";

    var repository = MockRepository.GenerateStub<IPersonDetailsRepository>();
    new SystemUnderTest(repository).CreatePerson(personName, personAddress);

    repository.AssertWasCalled(x => x.StorePersonDetails
                                     (Arg<PersonDetail>.Matches(person => person.Name == personName)));

    //Error: 
    //Rhino.Mocks.Exceptions.ExpectationViolationException:
    //IPersonDetailsRepository.StorePersonDetails(y => (y.Name = "John Smith")); Expected #1, Actual #0.
}

So, we caught the bug. However, I’d argue that it is not at all clear why the test failed. You’d have to look at the code under test. You cannot work out what went wrong by just looking at the error message. Is the error message telling us the dependency was not called at all, or that the argument sent was incorrect?

Rhino Mocks GetArgumentsForCallsMadeOn

The next Rhino Mocks method I’ll look at is one that I’ve discussed before. I think GetArgumentsForCallsMadeOn gives you a much clearer way to understand why your test failed:

[Test]
public void CheckPersonDetailsAreSaved_RhinoMocks_GetArgumentsForCallsMadeOn() {
    const string personAddress = "London";
    const string personName = "John Smith";
            
    var repository = MockRepository.GenerateStub<IPersonDetailsRepository>();
    new SystemUnderTest(repository).CreatePerson(personName,personAddress);

    var objectSentToRepository = (PersonDetail)repository
                                                  .GetArgumentsForCallsMadeOn
                                                       (r => r.StorePersonDetails(null))[0][0];
    Assert.That(objectSentToRepository.Name,Is.EqualTo(personName));
            
    //Error
    //NUnit.Framework.AssertionException:   Expected string length 10 but was 6. Strings differ at index 0.
    //Expected: "John Smith"
    //But was:  "London"
}

The error message you see in your test runner is clear – you know exactly what the bug in the code is. Much clearer than using the Matches syntax. However, you need an explicit cast and you are tying the test to the implementation in terms of parameter order of the dependency (see the caution at the bottom of my post about GetArgumentsForCallsMadeOn).

Moq

With Moq you also get an unclear assert error message:

[Test]
public void CheckPersonDetailsAreSaved_Moq() {
    const string personAddress = "London";
    const string personName = "John Smith";
    var repository = new Mock<IPersonDetailsRepository>();

    new SystemUnderTest(repository.Object).CreatePerson(personName, personAddress);

    //Both these give the same error seen below.
    repository.Verify(r=>r.StorePersonDetails(Match<PersonDetail>.Create(person => person.Name == personName)));
    repository.Verify(r=>r.StorePersonDetails(It.Is<PersonDetail>(x=>x.Name==personName)));

   //Error:
   //Moq.MockException: 
   //Invocation was not performed on the mock: 
   //x => x.StorePersonDetails(Match`1.Create(x1 => (x1.Name = "John Smith")))
}

Again, is the error message telling us the dependency was not called at all?

Fakes

There is another way. If your dependency interface is small, why not use a Fake object? – i.e. don’t use a Mocking Framework at all:

private const string personAddress = "London";
private const string personName = "John Smith";

private class FakeRepository : IPersonDetailsRepository {
    public PersonDetail CollectedPersonDetails;
    public void StorePersonDetails(PersonDetail personDetail) {
        CollectedPersonDetails = personDetail;
    }
}

[Test]
public void CheckPersonDetailsAreSaved_Moq() {
    var fakeRepository = new FakeRepository();
    new SystemUnderTest(fakeRepository).CreatePerson(personName, personAddress);

    Assert.That(fakeRepository.CollectedPersonDetails.Name, Is.EqualTo(personName));

    //Error:
    //NUnit.Framework.AssertionException:   Expected string length 10 but was 6. Strings differ at index 0.
    //Expected: "John Smith"
    //But was:  "London"
}

Using a fake, we have a simple, readable test and when there is an assert failure, it is obvious what the bug is.

Posted in Moq, Rhino Mocks, Test Driven Development | Tagged: , , | 1 Comment »

Recursive Mocks: Comparing Moq to Rhino Mocks

Posted by Kash Farooq on July 28, 2009

Here is the simple ASP.NET MVC code I want to test.
In a test, I need to mock the HttpContext so that it returns an identity that I control.

public ContentResult ReturnUserName() {
   return Content(User.Identity.Name);
}

And here is the test code using the released binaries of Rhino Mocks 3.5:

[Test]
public void ContentContainingUserNameReturned_RhinoMock() {
   var mockContext = MockRepository.GenerateStub<ControllerContext>();
   var mockHttpContext = MockRepository.GenerateStub<HttpContextBase>();
   mockContext.HttpContext = mockHttpContext;
   var identity = new GenericIdentity("user");
   mockHttpContext.User = new GenericPrincipal(identity,null);

   var controller = new HomeController {ControllerContext = mockContext};
   ContentResult content = controller.ReturnUserName();

   Assert.That(content.Content, Is.EqualTo("user"));
}

That’s a fair amount of mocking to test a one line method.

Here is the test using Moq:

[Test]
public void ContentContainingUserNameReturned_Moq() {
   var mockContext = new Mock<ControllerContext>();
   mockContext
     .SetupGet(x => x.HttpContext.User.Identity.Name)
     .Returns("user");

   var controller = new HomeController {ControllerContext = mockContext.Object};
   ContentResult content = controller.ReturnUserName();

   Assert.That(content.Content, Is.EqualTo("user"));
}

Far more concise.

The feature that allows Moq to do this is called Recursive Mocks.
You could argue that if you need to do this in your code then you must be breaking the Law Of Demeter. Sometimes, as with HttpContext, you don’t have a choice. Ayende argues you are breaking this law, but has introduced Recursive Mocking in Rhino Mocks, along with guidance. You’ll have to download the code and build you own binaries to use it though.

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

TDD with wrapper classes

Posted by Kash Farooq on January 12, 2009

Sometimes, during TDD, you come across a class that does not have an interface and therefore isn’t easy to test with Rhino Mocks. You’ll often find this is the case when you want to ensure that a class from the Base Class Library is being called correctly.
You can get around the problem using a wrapper class and an interface that describes the areas of the class you want to test.

For example, let’s say you have a method that uses System.Net.Mail.SmtpClient:

    public class SystemUnderTest {
        public void MethodUnderTest() {
            SmtpClient smtpClient=new SmtpClient();
            smtpClient.Port = 25;
            smtpClient.Host = "smtp.example.com";
            smtpClient.Send(new MailMessage{Subject = "Hello"});
        }
    }

SmtpClient is our external dependency. We want to test that the correct port and host has been set, and that Send is called with a MailMessage that has the subject “Hello”.

We start by creating an interface called ISmtpClient that includes the method and properties on SmtpClient that we want to test:

    public interface ISmtpClient {
        string Host { get; set; }
        int Port { get; set; }
        void Send(MailMessage mailMessage);
    }

We can now inject this into our system under test:
public class SystemUnderTest {      
   private readonly ISmtpClient smtpClient;

   public SystemUnderTest(ISmtpClient smtpClient) {
     this.smtpClient = smtpClient;
   }
        
   public void MethodUnderTest() {
      smtpClient.Port = 25;
      smtpClient.Host = "smtp.example.com";
      smtpClient.Send(new MailMessage{Subject = "Hello"});
   }
}

The test now becomes simple. Create a mock ISmtpClient, inject it into our system under test, and then assert that it was called correctly:

[Test]
public void MethodUnderTestSetsPortAndHostAndThenSendsMessage() {
	var mockRepository = new MockRepository();
	var smtpClient = mockRepository.DynamicMock<ISmtpClient>();

	mockRepository.ReplayAll();
	var systemUnderTest = new SystemUnderTest(smtpClient);
	systemUnderTest.MethodUnderTest();

	smtpClient.AssertWasCalled(x => x.Host = "smtp.example.com");
	smtpClient.AssertWasCalled(x => x.Port = 25);
	var mailMessage = (MailMessage)smtpClient.GetArgumentsForCallsMadeOn(x => x.Send(null))[0][0];
	Assert.AreEqual("Hello",mailMessage.Subject);
}

The final piece of the jigsaw is to wrap SmtpClient and implement ISmtpClient. The wrapper class will be used as the real implementation by the system under test:

public class SmtpClientWrapper : SmtpClient, ISmtpClient {}

Here is the final version of SystemUnderTest, using the wrapper class:

public class SystemUnderTest {
	private readonly ISmtpClient smtpClient;
	public SystemUnderTest() : this(new SmtpClientWrapper()) {}

	public SystemUnderTest(ISmtpClient smtpClient) {
		this.smtpClient = smtpClient;
	}

	public void MethodUnderTest() {
		smtpClient.Port = 25;
		smtpClient.Host = "smtp.example.com";
		smtpClient.Send(new MailMessage {Subject = "Hello"});
	}
}

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

 
Follow

Get every new post delivered to your Inbox.