Showing posts with label TDD. Show all posts
Showing posts with label TDD. Show all posts

Monday, March 29, 2010

A simple BDD “framework”

Last month I held a WPF presentation at work where I created a ViewModel class doing TDD. This got a little buzz because of the way I integrated BDD concepts in the tests. I have since then recieved a few question about how I actually did it. Let’s first have a look at what I did:
namespace Specifications_for_customer_search
{
    [Scenario]
    public class When_user_searches_for_customers : ScenarioBase
    {
        private RhinoAutoMocker<CustomerSearchViewModel> _mocks;
        private List<Customer> _customers;
        private string _customerName;

        public override void Given()
        {
            _mocks = new RhinoAutoMocker<CustomerSearchViewModel>();
            _customerName = "goran";
            _customers = new List<Customer> { new Customer(_customerName) };
            _mocks.Get<ICustomerRepository>().Stub(me => me.FindCustomerByName(Arg<string>.Is.Anything)).Return(_customers);
            
        }

        public override void When()
        {
            _mocks.ClassUnderTest.SearchCommand.Execute(_customerName);
        }

        [Then]
        public void should_query_customer_repository_for_matching_customers()
        {
            _mocks.Get<ICustomerRepository>().AssertWasCalled(me => me.FindCustomerByName(_customerName));
        }

        [Then]
        public void should_list_customers_found()
        {
            Assert.That(_mocks.ClassUnderTest.Customers, Is.EqualTo(_customers));
        }
    }
}
This was all done by using the base class from my previous post and renaming Arrange and Assert to Given and When. In this example I used NUnit, so I inherited from NUnit’s test attributes:
public class ThenAttribute : TestAttribute{}
public class ScenarioAttribute : TestFixtureAttribute { }
That was all. Happy testing! :)

Saturday, October 24, 2009

An AAA style BDD specification base class

Lately I have written a lot of Arrange, Act, Assert style tests using Rhino Mocks. I’ve also started to write more readable tests with a dash of BDD style naming like this:

[Fact]
public void Should_find_projects_when_user_searches()
{
 //Arrange
 var projectRepository = MockRepository.GenerateMock<IProjectRepository>();
 var projects = new List<Project> { ProjectMother.CreateProject("project 1"), ProjectMother.CreateProject("project 2") };
 projectRepository.Stub(me => me.FindByName(null)).IgnoreArguments().Return(projects);
 var presentationModel = new ProjectSearchPresentationModel(projectRepository);
 //Act
 presentationModel.SearchCommand.Execute("");
 //Assert
 projectRepository.AssertWasCalled(me => me.FindByName(""));
 Assert.Equal(projects.Count, presentationModel.Projects.Count);
}

The scenario for this test is “When the user searches”. If we look closely we see that it have two asserts. When the user searches it should ask the repository for projects and the result should be “displayed” in a list. This feels a bit odd. I have to create a name for the test that captures everything that has to be done when the user searches. This is hard and I’m likely to loose some of the intent. The solution is to split the test in a test for every assert. However, this means that I have to set up each test in an equal manner and call the serach command. This is DRY! To solve this I’ve created a test base class called Specification that enables me to write the above test like this:

namespace Specifications_for_project_search_presentation_model
{
 public class When_user_searches_for_projects : Specification
 {
     private ProjectSearchPresentationModel _presentationModel;
     private List<Project> _projects;
     private IProjectRepository _projectRepository;

     public override void Arrange()
     {
         _projectRepository = MockRepository.GenerateMock<IProjectRepository>();
         _projects = new List<Project> { ProjectMother.CreateProject("project 1"), ProjectMother.CreateProject("project 2") };
         _projectRepository.Stub(me => me.FindByName(null)).IgnoreArguments().Return(_projects);
         _presentationModel = new ProjectSearchPresentationModel(_projectRepository);
     }

     public override void Act()
     {
         _presentationModel.SearchCommand.Execute("");         
     }

     [Fact]
     public void should_search_repository()
     {
         _projectRepository.AssertWasCalled(me => me.FindByName(""));         
     }

     [Fact]
     public void should_show_result()
     {
         Assert.True(_presentationModel.CanShowProjects);
     }

     [Fact]
     public void should_list_projects_found()
     {
         Assert.Equal(_projects.Count, _presentationModel.Projects.Count);
     }
 }
}

I have now set up the context and called the search command only once, but have a seperate test for each assert. I think these kind of tests read nicely. I have a test class for each scenario and tests that reads like the specification for the scenario. This also look very good in ReSharper.

specifications

The base class is implemented like this for xUnit:

public abstract class Specification
{
 protected Specification()
 {
     Arrange();
     Act();
 }

 public abstract void Arrange();
 public abstract void Act();
}