Test Driven Development with ASP.Net MVC (Part 5)

The series in full:

In Part 4 of the series we implemented the first controller action of for the Event Controller in a Test Driven manner. As we are working from the outside-in it means that although the Controller action has been implemented, the layers beneath the Controller (the service layer and the repository in our case) are not yet implemented beyond creating anything needed by the layers above.

As the controller needed to call the service it was implemented in part 4, but is far from complete.

public class EventService : IEventService
{   
    public GetAllRegionsResponse GetAllRegions()
    {
        throw new NotImplementedException();
    }
}

The next step in the outside-in process is to build up the implementation of the service method guided by tests. The functionality for this service method is really simple so it shouldn’t take long to get it up and running. First we should Create a new Test Class to hold out service tests. I have separated out the service test into a separate namespace to aid navigation and readability of the test. I have also named the test class in such a way that when read in conjunction with the test name it gives a meaningful description of the intent of the test.

So what is the intent of the test for the GetAllRegions() service method? We would expect the service method to get all the regions so that they can be presented to the user in by the Event Controller. In this example we are going to have a repositories for data persistence. So this method is going to simply ask the repository for a list of regions, and then package them up to be returned to the Controller. Lets write the test.

public class EventServiceShould
{
    private EventService eventService;
    private Mock<IEventRepository> eventRepository;

    [TestMethod]
    public void ReturnAListOfAllTheRegions()
    {
        //Arrange
        eventRepository = new Mock<IEventRepository>();
        eventService = new EventService(eventRepository.Object);

        var regions = new List<Region>
                            {
                                new Region {Id = 1, Name = "North"},
                                new Region {Id = 2, Name = "South"},
                                new Region {Id = 3, Name = "London"}
                            };

        eventRepository.Setup(x => x.GetAllRegions()).Returns(regions);

        //Act
        var result = eventService.GetAllRegions();

        //Assert
        Assert.AreEqual(3,result.Regions.Count);
        Assert.AreEqual("South", result.Regions[1].Name);
    }
}

As before Resharper is telling us that there is a lot of implementation missing. Lets start with the Repository Interface. I have created another project for the repositories:

namespace CrazyEvents.Repositories
{
    public interface IEventRepository
    {
        List<Region> GetAllRegions();
    }
}

The Repository should always work with domain entities, and ours is no exception. Next up is the Region domain entity. Again I have created a new project to hold the domain items.

namespace CrazyEvents.Domain
{
    public class Region
    {
        public int Id { getset; }
        public string Name { getset; }
    }
}

And finally the service method implementation. This method has no logic, as we simply want to return all the regions. The only thing we need to do is to to take the regions returned from the repository and build the DTO’s for the Controller.

public class EventService : IEventService
{
    private readonly IEventRepository eventRepositoty;

    public EventService(IEventRepository eventRepositoty)
    {
        this.eventRepositoty = eventRepositoty;
    }

    public GetAllRegionsResponse GetAllRegions()
    {
        var regions = eventRepositoty.GetAllRegions();

        var regionDtos = regions.Select(region => new RegionDto {Id = region.Id, Name = region.Name}).ToList();

        return new GetAllRegionsResponse {Regions = regionDtos};
    }
}

Now the implementation is complete lets run the tests and make sure everything is okay.

All the tests are green which means that everything is going well. The implementation for the scenario is almost complete. Working from the outside in means that the only thing left to do at this point is the repository implementation.

As the repository will need to perform the data persistence (usually by talking to a database) it is not possible to isolate the implementation for unit testing in the same way as the controller or the service and is not generally part of an outside-in TDD approach. That is not to say it should not be tested. It would be prudent to create an integration test for the scenario including talking to a real database. Better yet, would be to use the scenario to create a BDD style test with a framework such as SpecFlow.

Once the repository method is complete, it is time to move onto the next slice of functionality and follow the same outside-in process.

The series in full:

About these ads

5 Responses to Test Driven Development with ASP.Net MVC (Part 5)

  1. Pingback: Test Driven Development with ASP.Net MVC (Part 4) « James Heppinstall: On Development

  2. Pingback: Test Driven Development with ASP.Net MVC (Part 1) « James Heppinstall: On Development

  3. Pingback: Test Driven Development with ASP.Net MVC (Part 2) « James Heppinstall: On Development

  4. Pingback: Test Driven Development with ASP.Net MVC (Part 3) « James Heppinstall: On Development

  5. Really nice article, I’ll use it as a guide for my upcoming MVC project :)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: