<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>TiMoch &#187; asp.net</title>
	<atom:link href="http://timoch.com/blog/tag/asp-net/feed/" rel="self" type="application/rss+xml" />
	<link>http://timoch.com/blog</link>
	<description>on edge</description>
	<lastBuildDate>Tue, 29 Apr 2014 15:02:50 +0000</lastBuildDate>
	<language>en-US</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=3.9.40</generator>
	<item>
		<title>Unit testing model validation with MVC&#8217;s DataAnnotations</title>
		<link>http://timoch.com/blog/2013/06/unit-testing-model-validation-with-mvcs-dataannotations/</link>
		<comments>http://timoch.com/blog/2013/06/unit-testing-model-validation-with-mvcs-dataannotations/#comments</comments>
		<pubDate>Fri, 21 Jun 2013 08:55:04 +0000</pubDate>
		<dc:creator><![CDATA[timoch]]></dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[asp.net]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[mvc]]></category>
		<category><![CDATA[unit-test]]></category>

		<guid isPermaLink="false">http://timoch.com/blog/?p=338</guid>
		<description><![CDATA[In a previous post, I mentioned that model validation should be tested separately from controller logic. I will demonstrate a way of unit testing the validation of models implemented with System.ComponentModel.DataAnnotations. It is actually quire easy to unit test model validation. Models are inherently easy to test separately due to their POD (Plain Old Data) nature. [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>In a previous post, I mentioned that model validation should be tested separately from controller logic. I will demonstrate a way of unit testing the validation of models implemented with <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.aspx">System.ComponentModel.DataAnnotations</a>.</p>
<p>It is actually quire easy to unit test model validation. Models are inherently easy to test separately due to their POD (Plain Old Data) nature. We can instantiate them directly. Moreover, DataAnnotations provides us with the necessary <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.validator.aspx">interface</a> to run the validation against a model object completely separately from the rest of the application.</p>
<h2>A first model validation test class</h2>
<p>Here is a basic model that we will unit test for the demonstration:</p><pre class="crayon-plain-tag">using System;
using System.ComponentModel.DataAnnotations;

namespace DataAnnotationsUnitTesting
{
    public class CreatePersonModel
    {
        [Required]
        public string FirstName { get; set; }
        [Required]
        public string LastName { get; set; }
        [Range(typeof (DateTime), "1900/01/01", "2000/01/01")]
        public DateTime BirthDate { get; set; }
        [RegularExpression(@"\+?\d+")]
        public string PhoneNumber { get; set; }
    }
}</pre><p>As you can see, it is quite simple. We&#8217;ll go directly to the unit test implementation.</p>
<p>The strategy we are going to use consists in basing each test case on a valid model instance, then modifying it in such a way that it triggers one single validation error. We end up with a skeleton unit test class like this:</p><pre class="crayon-plain-tag">using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using NUnit.Framework;

namespace DataAnnotationsUnitTesting {
    [TestFixture]
    public class CreatePersonModelValidationTests : AssertionHelper {
        private CreatePersonModel CreateValidPersonModel() {
            return new CreatePersonModel() {
                FirstName = "Some Name",
                LastName = "Some Last Name",
                BirthDate = new DateTime(1982, 07, 28),
                PhoneNumber = "+112233445566"
            };
        }

        public IEnumerable&lt;ValidateRuleSpec&gt; ValidationRule_Source() {
            yield break;
        }

        [Test]
        [TestCaseSource("ValidationRule_Source")]
        public void ValidationRule(ValidateRuleSpec spec) {
            // Arrange
            var model = CreateValidPersonModel();
            // Apply bad valud
            model.GetType().GetProperty(spec.MemberName).SetValue(model, spec.BadValue);

            // Act
            var validationResults = new List&lt;ValidationResult&gt;();
            var success = Validator.TryValidateObject(model, new ValidationContext(model), validationResults, true);

            // Assert
            Expect(success, False);
            Expect(validationResults.Count, EqualTo(1));
            Expect(validationResults.SingleOrDefault(r =&gt; r.MemberNames.Contains(spec.MemberName)), Not.Null);
        }

        public class ValidateRuleSpec {
            public object BadValue;
            public string MemberName;

            public override string ToString() {
                return MemberName + " - " + (BadValue ?? "&lt;null&gt;");
            }
        }
    }
}</pre><p>Some explanation:</p>
<ul>
<li><span style="line-height: 13px;">ValidateRule() implements the test itself. However, it gets the specifications for each test via an argument. </span></li>
<li>ValidateRule_Source() provides the specs for our test.</li>
<li>class ValidateRuleSpec holds the specifications. Its ToString() uses the spec values to render a distinct string per test. This makes unit test reports easy to read. In case of failure, you know exactly which spec failed.</li>
</ul>
<p>And now the implementation of our ValidateRule_Source():</p><pre class="crayon-plain-tag">public IEnumerable&lt;ValidateRuleSpec&gt; ValidationRule_Source() {
    yield return new ValidateRuleSpec() {
        BadValue = null,
        MemberName = "FirstName"
    };
    yield return new ValidateRuleSpec() {
        BadValue = string.Empty,
        MemberName = "FirstName"
    };
    yield return new ValidateRuleSpec() {
        BadValue = null,
        MemberName = "LastName"
    };
    yield return new ValidateRuleSpec() {
        BadValue = string.Empty,
        MemberName = "LastName"
    };
    yield return new ValidateRuleSpec() {
        BadValue = new DateTime(),
        MemberName = "BirthDate"
    };
    yield return new ValidateRuleSpec() {
        BadValue = DateTime.Today,
        MemberName = "BirthDate"
    };
    yield return new ValidateRuleSpec() {
        BadValue = "-65623",
        MemberName = "PhoneNumber"
    };
    yield return new ValidateRuleSpec() {
        BadValue = "abc",
        MemberName = "PhoneNumber"
    };
}</pre><p></p>
<h2>Refining the solution</h2>
<p>This works but can be improved. Most of the functionality can be abstracted. The actual test need only provide the valid model object and the specifications. A bit of refactoring yields a nicer design for our test:</p><pre class="crayon-plain-tag">using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using NUnit.Framework;

namespace DataAnnotationsUnitTesting {
    [TestFixture]
    public abstract class ModelValidationTestsBase : AssertionHelper {
        protected abstract CreatePersonModel CreateValidModel();

        public abstract IEnumerable&lt;ValidateRuleSpec&gt; ValidationRule_Source();

        [Test]
        [TestCaseSource("ValidationRule_Source")]
        public void ValidationRule(ValidateRuleSpec spec) {
            // Arrange
            var model = CreateValidModel();
            // Apply bad valud
            model.GetType().GetProperty(spec.MemberName).SetValue(model, spec.BadValue);

            // Act
            var validationResults = new List&lt;ValidationResult&gt;();
            var success = Validator.TryValidateObject(model, new ValidationContext(model), validationResults, true);

            // Assert
            Expect(success, False);
            Expect(validationResults.Count, EqualTo(1));
            Expect(validationResults.SingleOrDefault(r =&gt; r.MemberNames.Contains(spec.MemberName)), Not.Null);
        }

        protected ValidateRuleSpec Spec(string memberName, object badValue) {
            return new ValidateRuleSpec() {MemberName = memberName, BadValue = badValue};
        }

        public class ValidateRuleSpec {
            public object BadValue;
            public string MemberName;

            public override string ToString() {
                return MemberName + " - " + (BadValue ?? "&lt;null&gt;");
            }
        }
    }

    public class CreatePersonModelValidationTests : ModelValidationTestsBase {
        protected override CreatePersonModel CreateValidModel() {
            return new CreatePersonModel() {
                FirstName = "Some Name",
                LastName = "Some Last Name",
                BirthDate = new DateTime(1982, 07, 28),
                PhoneNumber = "+112233445566"
            };
        }

        public override IEnumerable&lt;ValidateRuleSpec&gt; ValidationRule_Source() {
            yield return Spec("FirstName", null);
            yield return Spec("FirstName", string.Empty);
            yield return Spec("LastName", null);
            yield return Spec("LastName", string.Empty);
            yield return Spec("BirthDate", new DateTime());
            yield return Spec("BirthDate", DateTime.Today);
            yield return Spec("PhoneNumber", "-65623");
            yield return Spec("PhoneNumber", "abc");
        }
    }
}</pre><p>Notice how we trimmed CreatePersonModelValidationTests to a minimum. The class ModelValidationTestsBase can now be used for most of our model validation unit tests.</p>
<p>What do you think?</p>
]]></content:encoded>
			<wfw:commentRss>http://timoch.com/blog/2013/06/unit-testing-model-validation-with-mvcs-dataannotations/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Asp.Net MVC: Testing your controller actions</title>
		<link>http://timoch.com/blog/2013/06/asp-net-mvc-testing-your-controller-actions/</link>
		<comments>http://timoch.com/blog/2013/06/asp-net-mvc-testing-your-controller-actions/#comments</comments>
		<pubDate>Mon, 10 Jun 2013 08:53:40 +0000</pubDate>
		<dc:creator><![CDATA[timoch]]></dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[asp.net]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[mvc]]></category>
		<category><![CDATA[nunit]]></category>
		<category><![CDATA[unit-test]]></category>

		<guid isPermaLink="false">http://timoch.com/blog/?p=318</guid>
		<description><![CDATA[I can&#8217;t say I like all the aspects of Microsoft ASP.Net MVC. But there is one aspect that I like though is the ability to unit test most of the components of your application. Standard ASP.Net did not prevent you from testing your application. However, the framework and documentation did not encourage you to organize [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>I can&#8217;t say I like all the aspects of Microsoft ASP.Net MVC. But there is one aspect that I like though is the ability to unit test most of the components of your application. Standard ASP.Net did not prevent you from testing your application. However, the framework and documentation did not encourage you to organize your application in a way that is testable.</p>
<p>ASP.Net MVC really pushes for loosely coupled components and as such, encourages unit testing. Your controllers are not much more than plain methods taking some input, executing some logic and returning an output. Your controller is not responsible for much in the end. Even though it is a central part of any functionality, its responsibility is reduced to implementing the logic for responding to a certain type of request. It relies on the framework configuration and conventions to call its methods in an appropriate way.</p>
<p>Understanding the extend of a controller&#8217;s responsibility is a key to writing good, concise unit tests. Sometimes, it&#8217;s easier to remember what it is <strong>not responsible for</strong>:</p>
<ul>
<li><span style="line-height: 13px;"><strong>Model binding</strong>: turning the encoded form data or routing information into .Net object. A controller action does not need to know and does not care that the id of the object your are updating is a part of your action&#8217;s path (eg. <pre class="crayon-plain-tag">/admin/tags/edit/my-tag</pre> ) or if it is provided in the form of an encoded form field (eg. <pre class="crayon-plain-tag">&lt;input type="text" name="tagSlug" /&gt;</pre> )</span></li>
<li><strong>Model validation</strong>: it may seem surprising but in most cases, your controller should not implement the validation logic. From a controller&#8217;s action point of view, is there really a difference between a person&#8217;s last name missing or an unknown phone number format ? As far as your hypothetical EditPerson action is concerned, there is a validation error. Model validation should be tested separately.</li>
<li><strong>Pure business logic</strong>: a controller action is meant to handle requests. Even though it does not directly cope with http intricacies, it still very close to the http request/response life cycle. For example, an action ComputeLoanSchedule that needs to return a loan amortization schedule should probably delegate the actual computation to a business service class (ILoanService.GetAmortizationSchedule()) whose sole purpose is to handle such computation. In the future, if you need to expose the amortization schedule feature as a web api, you will only need to implement another controller and call the same business service.</li>
</ul>
<p>In the end, your controller is<strong> only responsible for:</strong></p>
<ul>
<li><span style="line-height: 13px;"><strong>Delegating work to domain services</strong>: as stated above, the domain logic of your application should be logically separated from your UI layer. It also gives you the flexibility to scale your web application and business domain services. </span></li>
<li><strong>Returning an appropriate response</strong>: a controller&#8217;s action responds to a request by returning a response. The standard MVC Controller class expects your actions provide a result that will drive the way the response if created. eg. Returning a ViewResult will trigger view rendering and a RedirectToRouteResult may respond with an HTTP 302.</li>
</ul>
<h1>Unit testing a controller action</h1>
<p>When it comes to unit testing, the less to test, the better. As such, the limited responsibility of controller actions is a boon when writing unit tests. As an example, I will be using a very simple controller<pre class="crayon-plain-tag">TagsController</pre> . It is part of a blog-like website. Its role is to allow for the management of tags to be applied to other components of the application like articles etc.</p>
<p><pre class="crayon-plain-tag">TagsController</pre> exposes a CRUD-like set of functionality:</p>
<ul>
<li><span style="line-height: 13px;">Index: provides the user with a list of existing tags</span></li>
<li>Create: enables the creation of new tags</li>
<li>Edit: enables editing existing tags</li>
</ul>
<h2>The simple case</h2>
<p>We will focus on the index functionality for now. It is implemented as a single action on our TagsController:</p><pre class="crayon-plain-tag">public class TagsController : Controller {
    private ITagService tagService;

    public TagsController(ITagService tagService) {
        this.tagService = tagService;
    }

    public ActionResult Index() {
        var tags = this.tagService.GetAll().OrderBy(tag =&gt; tag.Name);
        return View("Index", tags);
    }

    /* ... */
}</pre><p>The TagsController constructor takes a ITagService. It provides our constructor access to the tags in our database. As you can see, the <pre class="crayon-plain-tag">Index()</pre> action method does only 2 distinct operations. First, it asks for the tags to display. Then, it tells the framework to render the &#8220;Index&#8221; view using the retrieved tags as a model.</p>
<p>With such a simple implementation, the unit test will be quite simple also. I&#8217;ll follow the usual AAA (Arrange-Act-Assert) pattern.</p><pre class="crayon-plain-tag">[Test]
public void Index_RetrievesAllTags() {
    // Arrange
    var mockService = new Mock&lt;ITagService&gt;();
    var controller = new TagsController(mockService.Object);
    mockService
        .Setup(s =&gt; s.GetAll())
        .Returns(new[] {
            new Tag {Slug = "tag1", Name = "Tag1"},
            new Tag {Slug = "tag7", Name = "Tag7"},
            new Tag {Slug = "tag4", Name = "Tag4"}
        });

    // Act
    var result = controller.Index() as ViewResult;

    // Assert
    Expect(result, Not.Null);
    Expect(result.ViewName, EqualTo("Index"));

    // ensure service was used
    mockService.Verify(s =&gt; s.GetAll(), Times.Once());

    // check view's model
    var tags = result.Model as IEnumerable&lt;Tag&gt;;
    Expect(tags, Not.Null);
    Expect(tags.Count(), EqualTo(3));
    // tags should be sorted
    Expect(tags.ToArray()[0].Slug, EqualTo("tag1"));
    Expect(tags.ToArray()[1].Slug, EqualTo("tag4"));
    Expect(tags.ToArray()[2].Slug, EqualTo("tag7"));
}</pre><p>The first part sets up an ITagService mock for TagsController to consume. We then simply call method <pre class="crayon-plain-tag">Index()</pre> .</p>
<p>The assertions start with making sure we got a non-null result of the ViewResult type. <pre class="crayon-plain-tag">Index()</pre>  should ask for the &#8220;Index&#8221; view to be rendered. I prefer explicitly specifying the view name to render in my controller action. I believe this reduces the mental gymnastic necessary when debugging action-view interactions.</p>
<p><pre class="crayon-plain-tag">mockService.Verify()</pre>  ensures<pre class="crayon-plain-tag">ITagService.GetAll()</pre>  was called.</p>
<p>I then proceed with checking the model provided to the view is consistent with the data from the mock service object. One of the requirements is that the tags are sorted by name.</p>
<p>As you can see in the Index unit test, there is a lot more code than the method being tested. This is also one of the reason why you should reduce the scope of your tests as much as you can.</p>
<h2>A more complex test case</h2>
<p>I&#8217;ll cover the &#8220;create a new tag&#8221; functionality. In this case, the functionality is implemented by a pair of actions. A parameter-less <pre class="crayon-plain-tag">Create()</pre>  action simply triggers the rendering of an empty tag editor (implemented by a view names &#8220;Save&#8221;. The other <pre class="crayon-plain-tag">Create()</pre>  action takes a <pre class="crayon-plain-tag">SaveTagModel</pre>  parameter and responds to form submissions. As such, it behaves differently in case there is a validation error or the tag already exists in the tag db.</p><pre class="crayon-plain-tag">public class TagsController : Controller
{
    /* ... */

    [HttpGet]
    public ActionResult Create() {
        return View("Save", new SaveTagModel() {IsNew = true});
    }

    [HttpPost]
    public ActionResult Create(SaveTagModel saveTagModel) {
        var existingTag = tagService.GetBySlug(saveTagModel.Slug);
        if (existingTag != null) {
            ModelState.AddModelError("TagExists", "A tag with that slug already exists");
        }

        if (!ModelState.IsValid) {
            saveTagModel.IsNew = true;
            return View("Save", saveTagModel);
        }

        tagService.Save(new Tag() { Name = saveTagModel.Name, Slug = saveTagModel.Slug });
        return RedirectToAction("Index");
    }

    /* ... */
}</pre><p>I&#8217;ll show the tests I put together to cover the functionality of <pre class="crayon-plain-tag">TagsController.Create()</pre> . The first of those test is ensuring the initial to Create() triggers the rendering of an empty tag editor. The tag editor is implemented by a view called &#8220;Save&#8221; shared between the <pre class="crayon-plain-tag">Create()</pre>  and <pre class="crayon-plain-tag">Edit()</pre>  operations. As you can see, I make sure the view is specified by name. I also make sure the model is in a state consistent with an empty<pre class="crayon-plain-tag">SaveTagModel</pre> .</p><pre class="crayon-plain-tag">[Test]
public void Create_ShowsEmptySaveEditor() {
    // Arrange
    var mockService = new Mock&lt;ITagService&gt;();
    var controller = new TagsController(mockService.Object);

    // Act
    var result = controller.Create() as ViewResult;

    //Assert
    Expect(result, Not.Null);
    Expect(result.ViewName, EqualTo("Save"));
    var saveTagModel = result.Model as SaveTagModel;
    Expect(saveTagModel, Not.Null);
    Expect(saveTagModel.IsNew, True);
    Expect(saveTagModel.Name, Null.Or.Empty);
    Expect(saveTagModel.Slug, Null.Or.Empty);
}</pre><p>The next 2 tests cover the behavior of the<pre class="crayon-plain-tag">Create(SaveTagModel tag)</pre>  action. That is the action that responds to form submission from the tag editor.  These tests need to cover the following</p>
<ul>
<li><span style="line-height: 13px;">What happens when invalid input is provided?</span></li>
<li>What happens when a tag exists with the same &#8216;slug&#8217;?</li>
<li>What happens upon success?</li>
</ul>
<p>It will not come as a surprise that I wrote 3 tests, one for each of the points. The first test ensure <pre class="crayon-plain-tag">Create()</pre>  behaves when provided with invalid data. This test demonstrates an important point. The controller is not aware and does not care what the actual model errors are. Its &#8216;invalid input&#8217; behavior is triggered by any model error. We want to reduce our controller logic as much as possible. There may be some cases where the controller&#8217;s action behave differently based on specific errors. If you can avoid it, do so. It is against the separation of concern. A controller is not responsible for validation.</p><pre class="crayon-plain-tag">[Test]
public void Create_ShowsEditorAgainOnInvalidInput() {
    // Arrange
    var mockService = new Mock&lt;ITagService&gt;();
    var controller = new TagsController(mockService.Object);

    // Act
    var saveTagModelArg = new SaveTagModel() {Slug = string.Empty, Name = "somename"};
    controller.ModelState.AddModelError("testerror", "test message");
    var result = controller.Create(saveTagModelArg) as ViewResult;

    //Assert
    Expect(result, Not.Null);
    Expect(result.ViewName, EqualTo("Save"));
    var saveTagModel = result.Model as SaveTagModel;
    Expect(saveTagModel, Not.Null);
    Expect(saveTagModel.IsNew, True);
    Expect(saveTagModel.Name, EqualTo("somename"));
    Expect(saveTagModel.Slug, Null.Or.Empty);
    Expect(result.ViewData.ModelState.IsValid, False);
}</pre><p>Considering what I have just said, there is an issue with the current implementation of <pre class="crayon-plain-tag">Create()</pre> . It checks that a tag does not exist. This is a form of validation and should probably be moved either to model validation (implemented by a custom validation attribute) or to the service (by adding a specific <pre class="crayon-plain-tag">ITagService.Create()</pre>  method). On the other hand, since the validation relies on a service component one could argue that it is part of the orchestration the controller is responsible for. I will leave it here because it is such a trivial validation. Anything more complex I would extract it and test it separately. My rule of thumb is: if it takes more than one unit test to cover a piece of validation in the controller, the validation should be moved to its own class.</p>
<p>Here is the test that covers that part.</p><pre class="crayon-plain-tag">[Test]
public void Create_ShowsEditorAgainOnDuplicateSlug() {
    // Arrange
    var mockService = new Mock&lt;ITagService&gt;();
    var controller = new TagsController(mockService.Object);
    mockService.Setup(s =&gt; s.GetBySlug("tag"))
        .Returns(new Tag("tag", "Tag"));

    // Act
    var saveTagModelArg = new SaveTagModel() {Slug = "tag", Name = "somename"};
    var result = controller.Create(saveTagModelArg) as ViewResult;

    //Assert
    Expect(result, Not.Null);
    Expect(result.ViewName, EqualTo("Save"));
    var saveTagModel = result.Model as SaveTagModel;
    Expect(saveTagModel, Not.Null);
    Expect(saveTagModel.IsNew, True);
    Expect(saveTagModel.Name, EqualTo("somename"));
    Expect(saveTagModel.Slug, EqualTo("tag"));
    Expect(result.ViewData.ModelState.IsValid, False);
}</pre><p>Last but not least, here is the test that covers the success path. Out action should have called <pre class="crayon-plain-tag">ITagService.Save()</pre>  with an appropriate argument and it should redirect us to the index page for our tags. As you can see, the redirection is tested against route values, not against an actual URI. The routing configuration is covered by another set of tests. This will be the subject of another post in the next few days.</p><pre class="crayon-plain-tag">[Test]
public void Create_SavesTagAndRedirectsOnSuccess() {
    // Arrange
    var mockService = new Mock&lt;ITagService&gt;();
    var controller = new TagsController(mockService.Object);
    var saveTagModelArg = new SaveTagModel() {Slug = "tag", Name = "somename"};
    mockService.Setup(s =&gt; s.Save(It.Is&lt;Tag&gt;(tag =&gt; tag.Slug == "tag" &amp;&amp; tag.Name == "somename")));

    // Act
    var result = controller.Create(saveTagModelArg) as RedirectToRouteResult;

    //Assert
    Expect(result, Not.Null);
    Expect(result.Permanent, False);
    Expect(result.RouteName, Null.Or.Empty);
    Expect(result.RouteValues["controller"], Null.Or.Empty.Or.EqualTo("Tags"));
    Expect(result.RouteValues["action"], EqualTo("Index"));
    mockService.VerifyAll();
}</pre><p></p>
<h1>Conclusion</h1>
<p>As you can see, even though our controller is quite simple (3 methods only and simple at that), we had to write quite a few lines of unit test code to cover all the code paths. If you want to keep your unit tests to a minimum, make sure you respect the separation of concern principle. Test each of the involved components separately and reduce to a minimum the contract between them. The less they know about the other, the easier it is to change one component without your change to ripple through your whole application.</p>
<p>In the next few posts, I will cover testing model binding and validation as well as routes.</p>
<p>Don&#8217;t hesitate to hail me in the comments or on <a href="https://twitter.com/TiMochOnEdge">Twitter</a></p>
]]></content:encoded>
			<wfw:commentRss>http://timoch.com/blog/2013/06/asp-net-mvc-testing-your-controller-actions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
