Angel \”Java\” Lopez on Blog

June 24, 2011

Writing An Application Using TDD (Part 5) Adding Views

Previous Post
Next Post

Now I have some tests in place, I add some MVC views in this step. You can download the code from my AjCodeKatas Google Project, under trunk/AppTdd/Step04. So, this post has few new tests: it shows how we can build the interface AFTER the tests, and WITHOUT having a database or service layer, yet.

First, I added a new Site.master master page and style.css (borrowed from another ASP.NET MVC project)

I added a new Home controller:

Then, I added a view using the context menu over the Index method:


I modified the master page code, to have a new entry in its menu:

I added a new view associated to Index action in Subject controller:

I selected the “List” view content, and “Subject” as the type to use in the model.

But the controller method is:

public ActionResult Index()
    return View(subjects);

It uses a subject list, that is injected in the constructor by the tests:

public SubjectController(IList<Subject> subjects)
    this.subjects = subjects;

But wait! That list is injected by the tests. Now, I should inject in the normal process of the controller, in its parameter-less constructor:

public SubjectController()
    : this(Domain.Instance.Subjects)

I added a Domain.Instance to use as our in-memory domain:

public class Domain
    private static Domain instance = new Domain();
    private Domain()
        this.Subjects = new List<Subject>()
            new Subject() { Id = 1, Name = "Mathematics" },
            new Subject() { Id = 2, Name = "Physics" },
            new Subject() { Id = 3, Name = "Biology" },
            new Subject() { Id = 4, Name = "Literature" }
    public static Domain Instance { get { return instance; } }
    public IList<Subject> Subjects { get; set; }

I changed the links generated in the Index view from:

to use the Id property as primary key:

This is the result:

I created the other views using the Visual Studio “Add View…” wizard:

I had some missing actions, I wrote a new:

public ActionResult Edit(int id)
    var model = this.subjects.Where(s => s.Id == id).FirstOrDefault();
    return View(model);

With tests! 😉

public void GetSubjectForEdit()
    IList<Subject> subjects = GetSubjects();
    SubjectController controller = new SubjectController(subjects);
    ActionResult result = controller.Edit(1);
    Assert.IsInstanceOfType(result, typeof(ViewResult));
    ViewResult viewResult = (ViewResult)result;
    Assert.IsInstanceOfType(viewResult.ViewData.Model, typeof(Subject));
    Subject model = (Subject)viewResult.ViewData.Model;
    Assert.AreEqual(1, model.Id);
    Assert.AreEqual("Mathematics", model.Name);

Curiously, I detected a “bad” test. I had written in my AddSubject test:

Assert.IsTrue(subjects.Any(s => s.Name == "Chemistry"));
Assert.AreEqual(4, subject.Id);

But the new id should be 5 (our testable list has 4 predefined subjects):

Assert.IsTrue(subjects.Any(s => s.Name == "Chemistry"));
Assert.AreEqual(5, subject.Id);

I fixed the code and the controller action, run the web application, and voila!

Main points:

– I am using an in-memory domain.

– The views run over the already tested actions

No service layer or persistence yet. Next steps: add more classes to domain (Books), service layer (using test), and some persistence.

Interesting related post about development with TDD without a database (or adding it after the tests) by @RonJeffries:

But We Need a Database … Don’t We? |

See? We Don’t Need a Database … Yet |

Keep tuned!

Angel “Java” Lopez

Blog at