Angel \”Java\” Lopez on Blog

March 22, 2011

Writing An Application Using TDD (Part 2) First List

Next post in this series
Previous post in this series

Thanks to a suggestion by @MartinSalias, I choose to develop a simple domain: my personal library, my books. In this first code iteration, I want to list the book genres: Physics, Mathematics, Biology, Literature… (similar to genres in MvcMusicStore by @jongalloway).

First, I created the ASP.NET MVC Solution (I’m using Visual Studio 2008) (the code for this post is in my AjCodeKatas Google Project, under trunk/AppTdd/Step01)

Then, I add a test project:

I added references to System.Web.Mvc and MyLibrary.Web, to be used in this test project.

I added a new test:

I cleaned the code of my first test class, removing unneeded methods. The result:

namespace MyLibrary.Web.Tests.Controllers
{
    using System;
    using System.Text;
    using System.Collections.Generic;
    using System.Linq;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    [TestClass]
    public class GenreControllerTests
    {
    }
}

Then, I added my first test:

        [TestMethod]
        public void GetGenres()
        {
            IList<Genre> genres = new List<Genre>()
            {
                new Genre() { Name = "Mathematics" },
                new Genre() { Name = "Physics" },
                new Genre() { Name = "Biology" },
                new Genre() { Name = "Literature" }
            };
            GenreController controller = new GenreController(genres);
            ActionResult result = controller.Index();
            Assert.IsNotNull(result);
            Assert.IsInstanceOfType(result, typeof(ViewResult));
            ViewResult viewResult = (ViewResult)result;
            Assert.IsInstanceOfType(viewResult.ViewData.Model, typeof(IList<Genre>));
            Assert.AreSame(genres, viewResult.ViewData.Model);
        }
		

The idea: create the controller, feed it with a list of genres, then invoke the Index action, and test the returned action result. The code didn’t compile: the controller didn’t exist, there were no Genre class. So, I wrote the Genre class in Model folder at MyLibrary.Web:

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

A simple GenreController (added with right click on Model folder):

The wizard created this code:

    public class GenreController : Controller
    {
        //
        // GET: /Genre/
        public ActionResult Index()
        {
            return View();
        }
    }

I modified it to have an appropriate constructor:

    public class GenreController : Controller
    {
        public GenreController()
        {
        }
        public GenreController(IList<Genre> genres)
        {
        }
        public ActionResult Index()
        {
            return View();
        }
    }
	

Note that my intention was to compile the test: the list of genres are not used by the controller, yet. With all these changes, I could compile the solution, and run the test:

The result was:

The problem:

As expected. This is part of the TDD cycle: compile, red, and now, go for green.

I changed the controller behavior (the interface was already completed):

    public class GenreController : Controller
    {
        private IList<Genre> genres;
        public GenreController()
        {
        }
        public GenreController(IList<Genre> genres)
        {
            this.genres = genres;
        }
        public ActionResult Index()
        {
            return View(genres);
        }
    }

Now, the test result:

Triumph of mind over matter! ;-)

Now, time for refactoring. Well, I have not much for this now. I could improve same naming. The main missing piece: a view. Note: the controller is not prepared, yet, for production. It has no genre provider object.

Next steps: improve controller to use a view, add CRUD actions with tests, and views.

You could ask: where is the repository of genres? where is the database? what about a service layer? domain separation? Ok, all valid questions. My idea is to show, with incremental steps, how all those artifacts arise from improving the controllers, actions, by the force of new tests and refactoring. As I wrote in my previous post, this is a kind of top-down approach. In this case, the domain is simple, so I can start from the top presentation layer. After this simple example, I will switch to a less simple domain. In this case, we can start testing the domain, before any presentation layer.

Keep tuned!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

5 Comments »

  1. Hi Maestro,

    I guess the first refactoring I would apply is to rename Genre(s) as Subject(s). Genre is used in literature, but not so much to classify other works. Subject is the term used in library reference system.

    Here is a nice article you may find useful for terms:
    http://en.wikipedia.org/wiki/Library_catalog

    Warmest regards,
    @martinsalias

    Comment by Martin Salias — March 23, 2011 @ 11:35 am

  2. Good to see you’re doing TDD. Why inject an IList, why not an IEnumerable? Why are the two assertions Assert.IsInstanceOfType(viewResult.ViewData.Model, typeof(IList)) and
    Assert.IsNotNull(result) necessary? What if the SUT changed the list? You check it is the same instance, but is it possible the elements were changed by the Sut? Nice glimpse of testing ASP .Net MVC. Thanks. Sean. @theHumanFlag on Twitter.

    Comment by Sean Bennett — March 23, 2011 @ 6:55 pm

    • Hi people!

      @MartinSalias: I will apply your suggestions; in the next posts, the example will be refactored to your names.

      @theHumanFlag: You are right, I could use IEnumerable. But I’m doing a little up front design. I could switch to IEnumerable, for the next posts.
      I’m using IsNull to have a better message, in case of error, to clearly distinguish between the case “data is null” from “data is not the expected type”.
      The SUT can change the elements, in the future. But my current expectations are: it doesn’t change them.

      Keep Tuned!

      Comment by Angel "Java" Lopez — March 26, 2011 @ 10:03 am

  3. [...] Writing an Application using TDD (Part 3) First Detail Filed under: .NET, Agile Software Devevelopment, ASP.NET MVC, C Sharp, Software Development, Test-Driven Development — ajlopez @ 9:47 am First post of this series Next post of this series Previous post of this series [...]

    Pingback by Writing an Application using TDD (Part 3) First Detail « Angel “Java” Lopez on Blog — March 28, 2011 @ 9:47 am

  4. [...] sugerencias que dejaron en comentarios @MartinSalias y @theHumanFlag, gracias! (las dejaron en el post en inglés). Primero, renombré la clase Genre a Subject, usando las capacidades de refactoring de Visual [...]

    Pingback by Escribiendo una Aplicación usando TDD (Parte 3) Primer Detalle - Angel "Java" Lopez — March 31, 2011 @ 9:55 am


RSS feed for comments on this post. TrackBack URI

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

The Shocking Blue Green Theme. Create a free website or blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 57 other followers

%d bloggers like this: