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
[...] 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
[...] 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