Friday 27 February 2015

Unit Testing ASP.NET MVC - Cheat Sheet

Mocking Request Cookie
var mockContext = new Mock<ControllerContext>();

mockContext.Setup(c => c.HttpContext.Request.Cookies).Returns(new HttpCookieCollection { new HttpCookie("test", "1") });

HomeController controller = new HomeController();
controller.ControllerContext = mockContext.Object;

var result = controller.Index()
Mocking Response Cookie
var mockContext = new Mock<ControllerContext>();

mockContext.SetupGet(c => c.HttpContext.Response.Cookies).Returns(new HttpCookieCollection());

HomeController controller = new HomeController();
controller.ControllerContext = mockContext.Object;

var result = controller.Index()

Assert.AreEqual(controller.ControllerContext.RequestContext.HttpContext.Response.Cookies["test"].Value, "1");

Mocking Request.IsAuthenticated
var mockContext = new Mock<ControllerContext>();
mockContext.SetupGet(x => x.HttpContext.User.Identity.Name).Returns("SOMEUSER");
mockContext.SetupGet(x => x.HttpContext.Request.IsAuthenticated).Returns(true);

var controller = new HomeController();
controller.ControllerContext = mockContext.Object;
Mocking ModeState.IsValid

ModeState.IsValid property is read only. But you can add an error to the ModelState to set the IsValid flag false indirectly.

var controller = new HomeController();
controller.ModelState.AddModelError("Error", "Model is invalid");
ViewResult result = controller.Index() // ModeState.IsValid will be false when Index() is executed. 
Mocking Dependency

MathController depends on an implementation of IMathService to complete the action. In the following example a mock instance of IMathService is passed to MathController to test the Add() method

Mock mathService = new Mock<IMathService>();
mathService.Setup(ms => ms.Add(1, 2)).Returns(3);

MathController controller = new MathController(mathService.Object);
var result = controller.Index(1, 2) as ViewResult;

Assert.AreEqual(result.ViewBag.Sum, 3);
mathService.Verify(ms => ms.Add(1,2), Times.Exactly(1));
Mocking Exception
Mock mathService = new Mock<IMathService>();
mathService.Setup(ms => ms.Add(1, 0)).Throws(new ArgumentException("Invalid argument(s)"));

MathController controller = new MathController(mathService.Object);

try
{
      var result = controller.Index(1, 0) as ViewResult;
}
catch(ArgumentException ex)
{
      Assert.AreEqual("Invalid argument(s)", ex.Message);
}
Testing RedirectResult

If your method returns a RedirectResult then you can check the result url against the expected

var controller = new RedirectController();

RedirectResult result = controller.SendMeSomewhereElse();

Assert.AreEqual("~/Some/Other/Place", result.Url);
Testing RedirectToRouteResult

If your method returns a RedirectToRoute i.e. if your action method returns RedirectToAction() or RedirectToRoute() then you can check the action name in RouteValues against the expected value. In the following example CustomerController.Create() is tested to check if the request is redirected to Index after creating the customer.

 var controller = new CustomerController();

var result = controller.Create(new Customer {Name = "Test"}) as RedirectToRouteResult;

Assert.AreEqual("Index", result.RouteValues["action"]);

Mocking HttpContext

Click here to see how to Mock HttpContext

Friday 13 February 2015

ActionResult types in ASP.NET MVC

ActionResult (System.Web.Mvc.ActionResult) Subtypes

ContentResult - Returns a user-defined content type.

Helper method: System.Web.Mvc.Controller.Content()

EmptyResult - Represents a return value that is used if the action method must return a null result (void).

Helper method: (None)

FileContentResult - Sends the contents of a binary file to the response.

Helper method: System.Web.Mvc.Controller.File()

FileStreamResult - Sends binary content to the response through a stream.

Helper method: System.Web.Mvc.Controller.File()

FilePathResult - Sends the contents of a file to the response.

Helper method: System.Web.Mvc.Controller.File()

HttpStatusCodeResult - Returns a specific HTTP response code and description.

Helper method: (None)

HttpUnauthorizedResult - Returns the result of an unauthorized HTTP request.

Helper method: (None)

HttpNotFoundResult - Indicates the requested resource was not found.

Helper method: System.Web.Mvc.Controller.HttpNotFound()

JavaScriptResult - Returns a script that can be executed on the client.

Helper method: System.Web.Mvc.Controller.JavaScript()

JsonResult - Returns a serialized JSON object.

Helper method: System.Web.Mvc.Controller.Json()

PartialViewResult - Renders a partial view, which defines a section of a view that can be rendered inside another view.

Helper method: System.Web.Mvc.Controller.PartialView()

RedirectResult - Redirects to another action method by using its URL.

Helper method: System.Web.Mvc.Controller.Redirect()

RedirectToRouteResult - Redirects to another action method.

Helper method: System.Web.Mvc.Controller.RedirectToAction() or RedirectToRoute()

ViewResult - Renders a view as a Web page.

Helper method: System.Web.Mvc.Controller.View()

MSDN >>

Wednesday 11 February 2015

How to add a section conditionally in ASP.NET MVC?

Here you go

@if(sectionRequired)
{
@:@section OptionalSection
{
<div class="content">
  Some text
</div>
}
}

You can set the Razor variable sectionRequired as required.

Deep cloning objects in JavaScript

There are a lot of ways to clone objects in Javascript and here are two of them.

Using JSON library

var person = {
    name: "Jack",
    age: 21,
    address: {houseNumber: 11, postcode: 'BR3'}
};
 
var jill = (JSON.parse(JSON.stringify(person)));
jill.name = "Jill";
 
console.log(person);
console.log(jill);

Using jQuery’s $.extend()

var person = {
    name: "Jack",
    age: 21,
    address: {houseNumber: 11, postcode: 'BR3'}
};
 
var jill = $.extend(true, {}, person);
jill.name = "Jill";
 
console.log(person);
console.log(jill);

$.extend() method is a little slower than the JSON exploit, but that shouldn’t really be a problem when you’re only doing a few clones.

Click here to read more

Using anonymous function as an alias to jQuery DOMReady function

Below syntax is a shorthand to jQuery.ready() function. The anonymous function passed to jQuery is only a callback function, it won't considered as a "JavaScript Module".

$(function(){
  
});

I.e. it does exactly the same thing that the below code block does, specify a function to execute when the DOM is fully loaded.

$(document).ready(function(){
  
});

But even though below code looks similar to the first syntax its is treated differently. This is called as module pattern or immediately invoking function in JavaScript

(function($) {
  
})(jQuery);

  • A module pattern or immediately invoking function executes immediately after it’s defined. It does not wait for the DOM to be ready.
  • Passing jQuery in to the parenthesis is to provide local scoping to the global variable.
  • All variables and functions defined within the anonymous function aren’t available to the code outside of it, effectively using closure to seal itself from the outside world.
  • To allow external code to access to a variable or function we can expose it to the global ‘window’ object.
    (function(){
      var foo = 'Hello';
      var bar = 'World!'
      
      function baz(){
          return foo + ' ' + bar;
      }
    
      window.baz = baz; //Assign 'baz' to the global variable 'baz'...
    })();
    
    console.log(baz()); 
    
Modules are a pattern of implementation that use an immediately invoking function to provide scope and privacy around a “module” of related functionality.

Click here to read more about JavaScript Module Pattern.

If the anonymous function passed to the DOM ready() method has lot of code in it then you can use an object literal to organize the handles and callbacks as shown in below example.

var dom = {
 
    onReady: function() {
        $( "#btn1" ).click( dom.animate);
    },
 
    animate: function( event ) {
        $( "#yayeffects" ).toggle();
    } 
};
 
$( document ).ready( dom.onReady );

Wednesday 4 February 2015

jQuery - How to get Html including the selector?

As you know jQuery .html() method can be used to get the HTML contents of the first element in the set of matched elements. But sometimes you might want to get the HTML including the container as well.

For example if you have below html

<div id="container">
 <div id="content">jQuery is awesome</div>
</div>

and if you use $('#container').html() it will give you

<div id="content">jQuery is awesome</div>
i.e. it returns the "innerHTML" of the "container" DIV.

There are many workarounds to it i.e. to get html including the "container".

Using wrap()

If you wrap the container in a dummy P tag you will get the container HTML as well.

var outerHtml  = $('#container').wrap('<p/>').parent().html();
Using clone()
var outerHtml = $("<div />").append($('#container').clone()).html();

Using wrap actually affects the DOM tree displayed to the user. This doesn't.