Angel \”Java\” Lopez on Blog

June 1, 2011

Writing An Application Using TDD (Part 4) Update and Insert

Previous Post
Next Post

In the previous post, I implemented the retrieve of one Subject data. No view is implemented yet. I’m writing the tests and then, implementing the code in the controller. It’s time to add a new Subject, using an action in the controller:

This was my first test:

[TestMethod]
public void AddSubject()
{
    IList<Subject> subjects = GetSubjects();
    Subject subject = new Subject() { Name = "Chemistry" };
    SubjectController controller = new SubjectController(subjects);
    ActionResult result = controller.Create(subject);
    Assert.IsNotNull(result);
    Assert.IsTrue(subjects.Any(s => s.Name == "Chemistry"));
    Assert.AreNotEqual(0, subject.Id);
}

GetSubjects() is a helper method presented in the previous post. It returns a list of test subjects. I added a new action in the controller class, so the solution could be compiled:

public ActionResult Create(Subject subject)
{
    throw new NotImplementedException();
}

The test was red:

Then, I completed the action method, with the minimal code to pass the test:

public ActionResult Create(Subject subject)
{
   subject.Id = this.subjects.Max(s => s.Id);
   subjects.Add(subject);
   return RedirectToAction("Index");
}

But I want to redirect to the details view for the new item. I added assertions to the test:

RedirectToRouteResult redirect = (RedirectToRouteResult)result;
Assert.IsTrue(string.IsNullOrEmpty(redirect.RouteName));
Assert.IsTrue(redirect.RouteValues.ContainsKey("id"));
Assert.AreEqual(subject.Id, redirect.RouteValues["id"]);
Assert.IsTrue(redirect.RouteValues.ContainsKey("action"));
Assert.AreEqual("Details", redirect.RouteValues["action"]);

I changed the action code, only to comply with the new requirement:

public ActionResult Create(Subject subject)
{
    subject.Id = this.subjects.Max(s => s.Id);
    subjects.Add(subject);
    return RedirectToAction("Details", new { id = subject.Id });
}

Now, the test is red:

I followed a similar path to write and pass the test for update a subject. This is the current version of the test:

[TestMethod]
public void UpdateSubject()
{
    IList<Subject> subjects = GetSubjects();
    Subject literature = subjects.Where(s => s.Name == "Literature").FirstOrDefault();
    Subject subject = new Subject() { Name = "SciFi" };
    SubjectController controller = new SubjectController(subjects);
    ActionResult result = controller.Update(literature.Id, subject);
    Assert.IsNotNull(result);
    Assert.IsInstanceOfType(result, typeof(RedirectToRouteResult));
    RedirectToRouteResult redirect = (RedirectToRouteResult)result;
    Assert.IsTrue(string.IsNullOrEmpty(redirect.RouteName));
    Assert.IsTrue(redirect.RouteValues.ContainsKey("id"));
    Assert.AreEqual(literature.Id, redirect.RouteValues["id"]);
    Assert.IsTrue(redirect.RouteValues.ContainsKey("action"));
    Assert.AreEqual("Details", redirect.RouteValues["action"]);
    Assert.IsTrue(subjects.Any(s => s.Name == "SciFi"));
    Assert.AreEqual(literature.Id, subjects.Where(s => s.Name == "SciFi").Single().Id);
}

The current controller action:

public ActionResult Update(int id, Subject subject)
{
    Subject toupdate = this.subjects.Where(s => s.Id == id).Single();
    toupdate.Name = subject.Name;
    return RedirectToAction("Details", new { id = id });
}

All the tests are green:

Some warnings: the tests are testing two ouputs: the change in the domain (a simple list) and the result action (an MVC concern). I should refactor (in an upcoming post) the implemention of the controller to separate the updates applied to the domain from the navigation results. I wrote the example in this way to show how to refactor the obtained code to have a better implementation. I could add tests that exercises the expected behavior when the subject to add is already in the domain, or the subject to update is missing.

Other note: there is no views yet. But I have the test in place to have confidence: when I added the views, I will have the expected behavior tested and in place.

Keep tuned!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

2 Comments »

  1. […] MVC, C Sharp, Software Development, Test-Driven Development — ajlopez @ 9:47 am First post Next post Previous […]

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

  2. […] ASP.NET MVC, C Sharp, Software Development, Test-Driven Development — ajlopez @ 11:23 am Previous Post Next […]

    Pingback by Writing An Application Using TDD (Part 5) Adding Views « Angel “Java” Lopez on Blog — June 24, 2011 @ 11:24 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

Blog at WordPress.com.

%d bloggers like this: