Easy ways to maximize the value of TDD

Before we’ve made it pass the first time, a failing test tells us what code to write.

When it fails later, it can tell us what we broke.  Failing tests alert us to regressions before we integrate.

A test is most valuable when it fails.

This is why the number-one-most-important rule of TDD is to maintain One Logical Assertion Per Test.  If you have more than one, a failing test becomes ambiguous.  This helps in writing the test and in understanding its failure, also known as diagnostics. 

When a test fails you should know exactly why.


Before we’ve written a test we must articulate the rationale behind the whole deal in the first place, and this process helps us reason abut the production system and its design.

After we’ve made it pass the first time, it becomes one in a suite of passing test cases we regularly run.   Now it can tell us what the system is doing in a way more understandable than the implementation code. 

A test is most valuable when it describes the behavior of the system rather than the implementation.

This is why the number-one-most-important rule of TDD is No Implementation Semantics.


Almost every time I’ve found myself struggling to deliver value with TDD it’s because I’ve failed to follow these two, coequal, number-one-most-important rules: One Logical Assertion Per Test and No Implementation Semantics

Posted in TDD | Leave a comment

Focusing on the controller's responsibility

The following is an excerpt from ASP.NET MVC 2 in Action, a book from Manning appearing in bookstores in May.  The early access (MEAP) edition is available now on http://manning.com/palermo2.  Authors include Jeffrey Palermo, Ben Scheirman, Jimmy Bogard, Eric Hexter and Matt Hinze.  Technically edited by Jeremy Skinner.

This selection is from chapter 19, Lightweight controllers.  All hyperlinks were added for this post.


A quick way to lighten the controller’s load is to simply remove responsibilities from it. Consider the burdened action, shown below:

A heavyweight controller
public RedirectToRouteResult Ship(int orderId)
{
   User user = _userSession.GetCurrentUser();
   Order order = _repository.GetById(orderId);

   if (order.IsAuthorized)
   {
      ShippingStatus status = _shippingService.Ship(order);

      if (!string.IsNullOrEmpty(user.EmailAddress))
      {
         Message message = _messageBuilder
            .BuildShippedMessage(order, user);

         _emailSender.Send(message);
      }

      if (status.Successful)
      {
         return RedirectToAction("Shipped", "Order", new {orderId});
      }
   }
   return RedirectToAction("NotShipped", "Order", new {orderId});
}

This action is doing a lot of work-it’s incomprehensible at first glance. You can almost count its jobs by the number of if statements. Beyond its appropriate role as director of the storyboard flow of the user interface, this action is deciding if the Order is appropriate for shipping and determining whether or not to send the User a notification email. Not only is it doing those things, but it’s deciding how to do them-it’s determining what it means for an Order to be appropriate for shipping and how the notification email should be sent.

Logic like this-domain logic, business logic-should generally not be in a user interface class like a controller. It violates the single responsibility principle, obfuscating both the true intention of the domain and the actual duties of the controller, which is redirecting to the proper action. Testing and maintaining an application written like this is difficult.

Cyclomatic complexity: source code viscosity

Cyclomatic complexity is a metric we can use to analyze the complexity of code. The more logical paths a method or function presents, the higher its cyclomatic complexity. In order to fully understand the implication of a particular procedure, each logical path must be evaluated. For example, each simple if statement presents two paths-one when the condition is true, and another when it’s false. Functions with high cyclomatic complexity are more difficult to test and to understand and have been correlated with increased defect rates.

A simple refactoring that can ease this is called Refactor Architecture by Tiers. It directs the software designer to move processing logic out of the presentation tier into the business tier.

After we move the logic for shipping an order to an OrderShippingService, our action is much simpler.

A simpler action after refactoring architecture by tiers
public RedirectToRouteResult Ship(int orderId)
{
   var status = _orderShippingService.Ship(orderId);
   if (status.Successful)
   {
      return RedirectToAction("Shipped", "Order", new {orderId});
   }
   return RedirectToAction("NotShipped", "Order", new {orderId});
}

Everything having to do with shipping the order and sending the notification has been moved out of the controller into a new class. The controller is left with the single responsibility of deciding where to redirect the client. The new class can fetch the Order, get the User, and do all the rest.

But the result of the refactoring is more than just a move. It’s a semantic break that puts the onus of managing these tasks in the right place. This change has resulted in a clean abstraction that our controller can use to represent what it was doing before. Other logical endpoints can reuse the OrderShippingService, such as other controllers or services that participate in the order shipping process. This new abstraction is clear, and it can change internally without affecting the presentation duties of the controller.

Refactoring doesn’t get much simpler than this, but a simple change can result in significantly lower cyclomatic complexity and can ease the testing effort and maintenance burden associated with a complex controller.

Posted in ASP.NET MVC | 6 Comments

JSON Hijacking in ASP.NET MVC 2

The following is an excerpt from ASP.NET MVC 2 in Action, a book from Manning appearing in bookstores in May.  The early access (MEAP) edition is available now on http://manning.com/palermo2.  Authors include Jeffrey Palermo, Ben Scheirman, Jimmy Bogard, Eric Hexter and Matt Hinze.  Technically edited by Jeremy Skinner.


JSON (pronounced like the English name, Jason) hijacking is a rare hack similar to XSRF, except it’s targeted to request secure JSON from vulnerable applications. The JSON hijacking process involves several steps:

1. A conspiring site, via JavaScript, instructs the victim’s browser to request some secure JSON data from another site.

2. The evil JavaScript receives the JSON data.

3. If the JSON is formatted as an array, the evil script can exploit browser JavaScript processing code to read the JSON data and transmit it back to the attacking site.

Allow JSON via POST only

The solution to this exploit offered by ASP.NET MVC 2 is to only accept requests for JSON data by HTTP POST requests, rather than by GETs. This is baked into and enforced by the standard JsonResult action result that ships with the framework. If we were to request data to be returned by JsonResult with a GET request, we wouldn’t receive the JSON data.

Listing 11.12 shows how we must issue a POST from JavaScript code requesting JSON data.

Listing 11.12 Requesting JSON data via POST
<script type="text/javascript">
    $.postJSON = function(url, data, callback) {
        $.post(url, data, callback, "json");
    };

    $(function() {
    $.postJSON('/post/getsecurejsonpost',
        function(data) {
            var options = '';
            for (var i = 0; i < data.length; i++) {
                options += '<option value="' +  #|2
                data[i].Id + '">' + data[i].Title +
                '</option>';
            }
            $('#securepost').html(options);

        });
    });
</script>

 <h2>Secure Json (Post)</h2>
  <div>
    <select id="securepost"/>
 </div>

Listing 11.12 uses the jQuery JavaScript library to craft a special POST request for our JSON data.  When the results are returned, the function populates the select list with them.

Override defaults for GET access

The problem with this approach isn’t technical-this works and it prevents JSON hijacking. But it’s a workaround that’s sometimes unnecessary and can interfere with systems developed using the REST architectural style.

If this approach causes problems, we have additional options. First, we can explicitly enable JSON requests from GETs with the code shown in listing 11.13.

Listing 11.13 Directing JsonResult to accept GETs
[HttpGet]
public JsonResult GetInsecureJson()
{
    object data = GetData();

    return Json(data, JsonRequestBehavior.AllowGet);
}

This will allow our action to respond to normal JSON GET requests. Finally, we can scrap JsonResult itself, instead using an action result to return only non-vulnerable, non-array formatted, JSON.

Modifying the JSON response

The code in listing 11.14 shows a special action result that wraps vulnerable JSON data in a variable, d.

Listing 11.14 Creating a SecureJsonResult encapsulates serialization logic
public class SecureJsonResult : ActionResult
{
    public string ContentType { get; set; }
    public Encoding ContentEncoding { get; set; }
    public object Data { get; set; }

    public override void ExecuteResult(ControllerContext context)
    {
         if (context == null)
         {
              throw new ArgumentNullException("context");
         }
         HttpResponseBase response = context.HttpContext.Response;
         if (!string.IsNullOrEmpty(ContentType))
         {
              response.ContentType = ContentType;
         }
         else
         {
              response.ContentType = "application/json";
         }
         if (ContentEncoding != null)
         {
              response.ContentEncoding = ContentEncoding;
         }
         if (Data != null)
         {
              var enumerable = Data as IEnumerable;
              if (enumerable != null)
              {
                    Data = new {d = enumerable};
              }
              var serializer = new JavaScriptSerializer();
              response.Write(serializer.Serialize(Data));
         }
    }
}

This action result encapsulates the tricky code to output the proper JSON, and it works well. The downside to this approach is that we must use this d variable in our JavaScript code. Listing 11.15 shows consuming the serialized data using jQuery.

Listing 11.15 Consuming SecureJsonResult with jQuery
$(function() {
$.getJSON('/post/getsecurejson',
    function(data) {
        var options = '';
        for (var i = 0; i < data.d.length; i++) {
            options += '<option value="' +
            data.d[i].Id + '">' + data.d[i].Title +
            '</option>';
        }
        $('#secure').html(options);
    });
});

Using this technique, we can still use GETs to retrieve our JSON data, but the JSON is secure because it’s never just an array-any arrays are wrapped in a d variable. We just must be sure to access values through the d variable.

This unconventional code can be confusing. We recommend using the default behavior of using HTTP POST requests to retrieve JSON data. If that becomes a problem, you can switch to this technique.

Posted in ASP.NET MVC | 3 Comments