Tuesday, 27 August 2013

Consuming Web API OData using $resource service of Angular JS

In one of the previous posts, we saw exposing an OData Endpoint from an ASP.NET Web API service and then we consumed it using .NET and JavaScript clients. In this post, we will continue with consuming the service using Angular JS.

$resource is a wrapper around $http service of Angular JS to interact with RESTful data services. If we use $resource, we don’t need to deal with the low level HTTP calls that we used to do with $http.

Since $resource is targeted for REST based services, it has to be configured with the service URL and a few of other optional settings to get it work. Following snippet shows syntax of a sample configuration:


$resource(url, { key:val, .. }, {
    ‘getValues’: {method: ‘GET’, params: { param: val }, … },
    …
    …
});


$resource is not a part of Angular’s core module. To use $resource in an Angular JS application, the module ngResource has to be injected into the module depending on it. To know more about $resource, visit the official documentation page on website of Angular JS.

$resource can be configured to perform all of its operations on a single URL or even the URL can be over-written in the action configuration, if required. To consume a Web API OData service, we need to use the second approach as the URL differs based on the operation we will be performing.

Following factory returns a $resource object to perform CRUD operations on the OData resource:


var app = angular.module('employeeApp', ['ngResource']);
app.factory('employeeSvc', function ($resource) {
    var odataUrl = "/odata/Employees";
    return $resource("", {},
    {
        'getAll': { method: "GET", url: odataUrl },
        'save': { method: "POST", url: odataUrl },
        'update': { method: 'PUT', params: { key: "@key" }, url: odataUrl + "(:key)" },
        'query': { method: 'GET', params: { key: "@key" }, url: odataUrl + "(:key)" },
        'remove': { method: 'DELETE', params: { key: "@key" }, url: odataUrl + "(:key)" }
     });
});


This factory can be injected inside any component and used there. Each action configured above is exposed as a method on the object returned from the factory with a dollar($) symbol prepended to each of them. Since these methods deal with AJAX, they return a $q promise.

Following controller uses the methods defined above to operate on the data service:


app.controller('EmployeeCtrl', function ($scope, employeeSvc) {

    //Getting all employees and assigning to a scope variable           
    function refreshEmployees() {
        (new employeeSvc()).$getAll()
            .then(function (data) {
                $scope.employees = data.value;
            });
    };

    //Add a new employee to the resource
    function createEmployee(emp) {
        return emp.$save();
    };

    //Modify details of an existing employee
    function editEmployee(emp) {
        return (new employeeSvc({
            "Id": emp.Id, "Name": emp.Name, "Salary": emp.Salary
        })).$update({ key: emp.Id });
    };

    //Delete an employee
    function deleteEmployee(id) {
        return (new employeeSvc()).$remove({ key: id });
    };

    //rest of the controller definition.......
});


Take a look at the refreshEmployee function created above. It calls then() on the returned object from the $getAll() method to grab the response as soon as the GET request is completed. As Web API OData sets actual data to the property value, the scope variable is assigned with this property.

Happy coding!

Monday, 26 August 2013

Consuming Web API OData From .NET And JavaScript Client Applications

In last post, I created a Web API OData service that performs CRUD operations on an in-memory collection. In this post, we will consume the service from a .NET client and a web page.

Consuming Web API OData using a .NET client:

A Web API OData service can be consumed using WCF Data Services client. If you gave already worked with WCF Data Services, you already know about consuming Web API OData Service as well.

Right click on a .NET project and choose the option Add Service Reference. In the dialog, enter the OData service URL and click the Go button.



The dialog parses the metadata received from the server and shows the available entities under container as shown in the screenshot. As we created just one entity in the service, we see the entity Employee alone. Name the namespace as you wish and hit OK. Visual Studio generates some classes for the client application based on the metadata.

The generated code contains the following:

  1. A Container class, which is responsible for communicating with the service. It holds DataServiceQuery<TEntity> type properties for each EntitySet on the server
  2. A class for every entity type. This class contains all properties mapped on the server, information about key of the entity

A Container is much like a DbContext in Entity Framework. It handles all the operations. Container is responsible for building OData URLs and sending requests to the service for any operation that client asks for. Let’s start by creating a Container. Constructor of the container accepts a URI, which is base address of the Web API OData service.

Container container = new Container(new Uri("http://localhost:1908/odata"));


To fetch details of all employees, we need to invoke the Corresponding DataServiceQuery property.


var employees = container.Employees;

Although the statement looks like an in-memory operation, it generates the corresponding URL internally and calls the server. Similarly, to get details of an employee with a given Id, we can write a LINQ query as shown:

var employee = container.Employees.Where(e => e.Id == 3).FirstOrDefault();

The above query makes a call to the Get method accepting key in the Web API Controller.

To create a new employee, we need to create an object of the Employee class, add it and ask Container to save it. Following snippet demonstrates this:


Employee emp = new Employee() { Id = 0, Name = "Hari", Salary = 10000 };
container.AddToEmployees(emp);
container.SaveChanges();

Performing update is also much similar. The difference is with calling the SaveChanges method.

emp = container.Employees.Where(e => e.Id == 3).FirstOrDefault();
emp.Name = "Stacy";
container.UpdateObject(emp);
container.SaveChanges(SaveChangesOptions.ReplaceOnUpdate);

If SaveChanges is called with SaveChangesOptions.ReplaceOnUpdate, it performs PUT operation on the resource. If SaveChangesOptions.PatchOnUpdate is passed, it performs PATCH operation on the resource.

To delete an entry, we need to pass an object to DeleteObject method and just like earlier cases; we need to call the SaveChanges method on the Container.


container.DeleteObject(container.Employees.Where(e => e.Id == 3).FirstOrDefault());
container.SaveChanges();


Consuming Web API OData using JavaScript client:

To consume the Web API OData service from a web page, the service has to be called using AJAX. The client can send an AJAX request to the URL of the OData service by specifying an HTTP verb to operate on the resource. To make our life easier, let’s use jQuery for AJAX calls.

To get details of all employees, we need to send a GET request to the OData URL. Values of entries in the collection are stored in a property named value in the object received as response. Fetching details of an employee with a given Id also follows similar approach. Following snippet demonstrates this:


$.getJSON(“/odata/Employees”, function(data){
    $.each(data.value, function(){
        //Modify UI accordingly
    });
});

$.getJSON(“/odata/Employees(3)”, function(data){
        //Modify UI accordingly
});


To add a new employee, we need to send the new object to $.post along with the URL.

var employee = {
    "Id": 0,
    "Name": “Ravi”,
    "Salary": 10000
};

$.post(“/odata/Employees”, employee).done(function(data){
    //Modify UI accordingly
});


Unfortunately, jQuery doesn’t have a shorthand method for PUT. But it is quite easy with $.ajax as well. To perform PUT on the resource, the request should be sent to the specific address with an ID and the modified object should be passed with the request.

var employee = {
    "Id": 3,
    "Name": “Ravi”,
    "Salary": 10000
};

$.ajax({
url: "/odata/Employees(" + employee.Id + ")",
       type: "PUT",
       data: employee
});


Building request for DELETE is similar to put, we just don’t need to pass the object.

$.ajax({
url: "/odata/Employees(" + id + ")",
type: "DELETE"
});


Happy coding!

Saturday, 24 August 2013

Performing CRUD Operations in Web API OData Service using ODataController

OData is a protocol for operating on data over HTTP. OData follows REST architecture. It provides a uniform interface for interacting with data over web and performing CRUD (Create, Read, Update and Delete) operations. It also provides metadata so that the consuming application gets awareness about the types used in the service.

If you are new to OData and want to learn more, checkout the official website for OData and read David Chappel’s whitepaper on OData.

ASP.NET Web API is a solution for creating HTTP services. ASP.NET team added OData support to Web API in the ASP.NET and Web Tools 2012.2 Update. In this post, we will create a simple Web API OData service that performs CRUD operations on an in-memory object collection.

Setting up the project and data:

Fire Visual Studio 2012 or 2013 and create an ASP.NET MVC 4 project with Web API template or, add the following NuGet packages to an empty ASP.NET project:

  • Microsoft.Aspnet.WebApi.OData
  • Microsoft.AspNet.WebApi.WebHost

Let’s create our data components now. Add a new class to the project, name it Employee and add following properties to it:

public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
    public double Salary { get; set; }
}
Add another class named EmployeesHolder. This class will hold a static collection of Employee class created above. We will perform CRUD operations on the data created in this class. Add the following code to the EmployeesHolder class:
public class EmployeesHolder
{
    public static List<Employee> Employees;

    static EmployeesHolder()
    {
        Employees = new List<Employee>();

        Employees.Add(new Employee() { Id = 1, Name = "Jack", Salary = 10000 });
        Employees.Add(new Employee() { Id = 2, Name = "Anthony", Salary = 7000 });
        Employees.Add(new Employee() { Id = 3, Name = "Tracey", Salary = 20000 });
        Employees.Add(new Employee() { Id = 4, Name = "Sherry", Salary = 6000 });
        Employees.Add(new Employee() { Id = 5, Name = "Hill", Salary = 16000 });
    }
}

Creating OData Route

We need to add some configurations when application starts to enable OData in the application. Before defining the route map, we need to build an EDM model with all entity sets to be exposed. It is done as shown below:

     var modelBuilder = new ODataConventionModelBuilder();
     modelBuilder.EntitySet<Employee>("Employees");
     Microsoft.Data.Edm.IEdmModel model = modelBuilder.GetEdmModel();

The ODataConventionalModelBuilder is used to map all entity sets that have to be exposed through OData endpoint. Alternatively, ODataModelBuilder can also be used for this purpose. But if we do so, we need to define each property and relationship using fluent configuration model. ODataConventionalModelBuilder does all that work for us. We just need to add the entity sets to be exposed.

We need to define the OData route using the EDM model created above. It is shown below:

config.Routes.MapODataRoute("ODataRoute", "odata", model);


Creating API Controller and performing read operations


Let’s define a Web API controller to perform CRUD operations over the collection created above. Add an API controller to the application named EmployeesController. Modify the parent class of this class as ODataController.
public class EmployeesController : ODataController
{
}

ODataController is the low-level class to work with OData in Web API. We need to directly deal with HTTP verbs and build response by hand using this class. We have higher level classes available that deal with the verbs. While using them we have to just worry about the data, rest of the things are taken care by the framework. But it is important to understand what is going on behind the scenes to get much of the work done. So, in this post we will create the API using ODataController.

Delete all the default code inside the controller. Add the following method to the controller:

public IQueryable<Employee> Get()
{
    return EmployeesHolder.Employees.AsQueryable();
}

Build and run this application now. Change the URL on your browser to:


http://localhost:<port-no>/odata/Employees


You should be able to see the list of all employees created above in your browser.



Notice the metadata URL in the first statement. Metadata information for the entire application is exposed through this URL.

Let’s add another method to the service that gets details of an employee based on ID.


public HttpResponseMessage Get([FromODataUri]int key)
{
    Employee employee = EmployeesHolder.Employees.Where(e => e.Id == key).SingleOrDefault();
    if (employee==null)
    {
        return Request.CreateResponse(HttpStatusCode.NotFound);
    }

    return Request.CreateResponse(HttpStatusCode.OK, employee);
}


The attribute FromODataUri indicates that the value has to be taken from the requested URL. Change the URL on the browser as:


http://localhost:1908/odata/Employees(2)


Now you should be able to see details of the second employee on the browser:



Web API OData supports a number of query options that can be used to query data from client application. We will explore those options in a future post.

Performing Create operation

HTTP Post method is for adding an item to the resource. It usually accepts data from the client in the HTTP request body. Following Post method adds a new employee to the list we created earlier:

public HttpResponseMessage Post([FromBody]Employee entity)
{
    string name = entity.Name;
    HttpResponseMessage response;
    double salary = entity.Salary;

    try
    {
        int employeeId = EmployeesHolder.Employees.Max(e => e.Id) + 1;

        entity.Id = employeeId;
        EmployeesHolder.Employees.Add(entity);

        response = Request.CreateResponse(HttpStatusCode.Created, entity);
        response.Headers.Add("Location", Url.ODataLink(new EntitySetPathSegment("Employees")));
        return response;
    }
    catch (Exception)
    {
        response = Request.CreateResponse(HttpStatusCode.InternalServerError);
        return response;
    }
}

As you see, the POST method returns a HttpResponseMessage object with the newly created entity embedded in the body. Location is explicitly added to the message because according to the HTTP specification, the location header has to be added to the response header once a POST request is succeeded. The API checks it and the consuming client will return an error if the location is not added.

To test this method, open Fiddler and switch to composer tab. Select POST method from the dropdown and enter the new employee object in JSON format in the request body as shown:



We can assign any value to Id. It will be ignored as we are calculating the next Id in the logic. Hit the Execute button to invoke the service method. Once you see the success status in fiddler, refresh the browser to see the updated employees list.



Performing Update Operation

Update can be performed using either patch or put verb. The difference between these verbs is patch performs partial update on the resource, whereas put replaces the entire entry with the new object received from the client. One of these or both can be chosen based on the needs of the application.

Following Put method modifies the entry at the provided Id in the Employees collection:


public HttpResponseMessage Put([FromODataUri]int key, [FromBody]Employee employee)
{
    var employeeToDeleteEdit = EmployeesHolder.Employees.Where(e => e.Id == key).FirstOrDefault();
    HttpResponseMessage response;
    string name = employee.Name;
    var salary = employee.Salary;

    int index = EmployeesHolder.Employees.FindIndex(e => e.Id == key);
    if (index >= 0)
    {
        EmployeesHolder.Employees[index].Name = name;
        EmployeesHolder.Employees[index].Salary = salary;
    }
    else
    {
        response = Request.CreateResponse(HttpStatusCode.NotFound);
        return response;
    }

    response = Request.CreateResponse(HttpStatusCode.OK, employee);
    return response;
}


Compose a PUT request on Fiddler as shown below:


Click on the Execute button to invoke the corresponding service method. Once the response is received from the server, refresh the browser to see the updated result.



Performing Delete Operation

Delete is a straight forward operation. It just accepts a key and deletes the object at that entry from the resource.


public void Delete([FromODataUri]int key)
{
    var employeeToDelete = EmployeesHolder.Employees.Where(e => e.Id == key).FirstOrDefault();
    if (employeeToDelete != null)
    {
        EmployeesHolder.Employees.Remove(employeeToDelete);
    }
    else
    {
        throw new HttpResponseException(HttpStatusCode.NotFound);
    }
}


Just like Post and Put, let’s test this method using Fiddler. Set a delete request as shown below:



Delete doesn’t accept any object in the body. Click the execute button and once the response is received, refresh browser to see the updated values.



As mentioned earlier, ODataController is the low-level class that helps us in building OData service. Web API’s OData assembly includes another controller that handles most of the plumbing like defining API methods and dealing with HttpResponseMessage. It is EntitySetController.We just need to override a set of methods to work with data in the data while using EntitySetController. Most of the tutorials on ASP.NET site use EntitySetController to work with OData.

Happy coding!

Thursday, 25 July 2013

Behaviour of Scope in Angular JS Directives

Directive is the coolest and most crucial feature provided by Angular JS. Use of scope in directives makes the process of writing a directive challenging. Behaviour of scope depends on the way it is assigned in the directive. Following are different scenarios of using scope inside directive:

  • Scope not assigned or set to false
  • Scope set to true
  • Isolated scope

Following is a simple controller with just one value assigned to scope that we will be using in a sample page:
var app = angular.module("myApp", []);

app.controller("SampleCtrl", ['$scope', function ($scope) {
    $scope.val = 0;
}]);


Let’s have a look at each of the above scenarios individually.

Scope not assigned or set to false:
Consider the following directive:
app.directive("dirWithoutScope", function () {
    return{
        scope:false,
        link: function (scope, elem, attrs, ctrl) {
            scope.val=20;
        }
    }
});

As the directive is not making any changes, scope of this directive remains same as the scope of its parent element. The statement in the link function modifies value of the property val, which is set in the controller. Both of the following span elements will display same value, which is 20.
<span>{{val}}</span>

<span dir-without-scope>{{val}}</span>


Scope set to true:
In this case, scope of the directive would be prototypically inherited from scope of its parent element. Let’s consider the following directive:

app.directive("dirWithScopeTrue", function () {
    return{
        scope:true
    }
});

As the scope is prototypically inherited, properties of the parent scope are accessible using this scope. The following span tag will still hold the value assigned to the parent scope:
<span dir-with-scope-true>{{val}}</span>

Let’s complicate the scenario a bit by adding the following link function to the above directive:
link: function (scope, elem, attrs, ctrl) {
    scope.val=25;
}

The value 25 isn’t assigned to the val property in the parent scope. Instead, this statement creates a new property in the child scope and assigns the value to it. The span element created above will hold the value 25 now.

If the value is set through $parent property of the scope, the value gets assigned to the parent scope.

$scope.$parent.val=25;

If statement of link function is replaced with the above statement, values in all span elements will change to 25.

Isolated scope:
If a new scope is created in the directive, the scope doesn’t inherit from the parent scope anymore. Properties of the parent scope are not accessible with the new scope. Following directive contains an isolated scope:

app.directive("dirWithBlankScope", function(){
    return{
        scope:{
        },
        link:function(scope, elem, attrs, ctrl){
            scope.val=30;
        }
    }
});

The assignment statement in the link function creates a property val in the new scope. It doesn’t alter the value of the property assigned in the controller or the previous directive. Following span prints value of the new property:
<span dir-with-new-scope>{{val}}</span>

Properties of the scope of parent element are still accessible through $parent property of the scope.
<span dir-with-new-scope>{{$parent.val}}</span>



Happy coding!

Monday, 22 July 2013

Isolate your tests from dependencies with TypeMock’s Isolator

Software development process is continuously evolving. One of the most talked practices in current era is Test Driven Development (TDD). There can’t be a day when I get into twitter and not seen some tweets on TDD and Unit testing. After some days, we may see very less number of projects that don’t have unit tests written.

If a piece of code is driven by tests, the code will not only have less bugs but the developers also spend some time to refactor and make the code cleaner. This makes the job of future developers easier, as they don’t have to take pain to write unit tests for a small piece that they write to add a new feature to the existing giant code base.

But we have a huge number of legacy projects for which we don’t have unit tests written. As most of such projects were not written with layers and abstractions, one will be more than scared to write automated unit tests for them. But these projects shouldn’t be left behind. A mocking framework with capability to mock out tight dependencies will make the work easier.

TypeMock’s Isolator is a right choice to pick in such scenarios. There are three versions of Isolator; the details on these versions are available on the product page.

To start using Isolator in a unit test project, a couple of assembly references have to be added. These dlls are added to GAC once you install Isolator. In C# projects, we need the references that are highlighted in the following screenshot.



In VB.NET projects, a reference to Typemock.Isolator.VisualBasic has of be added. These namespaces have to be included in the unit test class and the test methods have to be decorated with Isolate attribute as shown:


[TestMethod, Isolated]
public void Should_Set_value_To_Orders()
{

}


This attribute is used to keep each test method independent of each other.

Isolator has a uniform interface for mocking. Meaning, the API syntax to mock abstract types and concrete types is the same. Let us see how Isolator makes the process of writing unit tests easier in action.

Mocking interfaces
Let’s consider the following interface:


public interface IOrdersView
{
        IEnumerable<Order> Orders { get; set; }
        string this[string key] {get;}
        event EventHandler<EventArgs> LoadOrders;
}


It is a very generic interface which will be implemented by a view and can be used in any type of application. Let’s assume that it is used in an ASP.NET application following Model-View-Presenter pattern. The presenter will hold a reference of this interface type. While writing tests for the presenter, we need a mock object of this interface. Following statement creates the mock for us:

IOrdersView ordersView = Isolate.Fake.Instance<IOrdersView>();


Let’s fake behaviour of each of the component now. Let’s start with the property Orders.

Isolate.WhenCalled(()=>ordersView.Orders).WillReturn(new List<Order>(){
    //Use collection initializer to set values
       });


As we see, it is quite easy to skip mock implementation and return some custom values. The same API can be used to mock a method as well. Following statement fakes the event load orders.

Isolate.Invoke.Event(() => ordersView.LoadOrders += (s, e) => { 
     //A custom mock implementation goes here
      });


It is not necessary to implement a handler; it can be skipped by assigning null to the event handler. If the event accepts parameters, they can be passed after the mock implementation.

Faking an indexer is also similar to faking methods. While faking a method accepting parameters or indexers, we must specify value of the argument. Following statement is used to return a custom value when the indexer is asked to provide value of ID:


Isolate.WhenCalled(() => orders["ID"]).WillReturn("1");


Mocking Concrete types
Most of the legacy applications don’t follow rules of separation of concerns that we talk these days. For instance, if we take an old ASP.NET web forms based application, the code behind of each of the form is very heavily loaded with code. Testing such classes is not easy. Most scary object to deal with in ASP.NET code behind is HttpContext. This single object has a bunch of properties that are set by the web server when the application starts. Isolator’s API has a method that fakes all the properties in one go.


Isolate.WhenCalled(() => HttpContext.Current).ReturnRecursiveFake();


If there is a need to return some specific values when certain properties are invoked, you can do that using same API that we used for mocking interfaces. It is shown below:

var httpContextFake = Isolate.Fake.Instance<HttpContext>();
Isolate.WhenCalled(() => httpContextFake.Session["UserId"]).WillReturn("U001");
Isolate.WhenCalled(() => HttpContext.Current).WillReturn(httpContextFake);


Many applications contain a data access layer that is responsible to hit the database to operate on data from the application. Before technologies like Entity Framework came in, most of the projects used to perform database operations using ADO.NET. While writing tests for logic involving objects of SqlConnection and SqlCommand, we must prevent the tests from hitting the database. Isolator makes it possible to replace the actual objects with mocked objects on the fly. Following snippet demonstrates it:

var sqlCommandInstance = Isolate.Fake.Instance<SqlCommand>();
Isolate.Swap.NextInstance<SqlCommand>().With(sqlCommandInstance);


The first statement that creates the fake instance of SqlCommand mocks all methods defined in the class as well. After these statements, if we instantiate the data access layer and call a method that uses ExecuteNonQuery, then the call won’t hit the physical database. It will invoke the fake method that is just created.

These are some of the most common scenarios that we face during unit testing. Isolator is capable of doing much more than what is discussed here. Some of the eye-catching features include mocking:

  1. LINQ queries
  2. Private members
  3. Static members
  4. Counting calls
  5. Extension methods

To learn more on Typemock’s Isolator, you may visit the product page and checkout the online documentation.

Happy coding!

Saturday, 20 July 2013

Basics: Architecture of Modern Client Applications

We can no longer imagine a day without an app running on one of the electronic devices that we hold in our hands. Developers are actively creating apps for different purposes. May it be social media, weather report, news, stock market, even on quotes of your favourite philosopher and many others! So there are good numbers of chances that new people getting into programming turn into app developers. In this post, we will take a look at the architecture of client applications in general and a common question that I usually get from developers.

We have different kinds of client applications available these days. Following are some examples of client applications:

  • Apps that run on smart phones like iPhone, Android, Windows phone or any such device
  • Windows 8 Store apps
  • Applications like Google talk, Yahoo messenger, MetroTwit that run on any OS

Any kind of application must have two basic components: UI and Data. In context of modern client applications, they work as follows:

  • UI of modern client applications is rendered completely on the client’s device, because of which the user gets very rich experience
  • The app can use data stored in the device or it may fetch data with help of services that are hosted on a server. These services are responsible to connect to database and operate on the data

Following is a pictorial representation of the above points:




A common question:

Developers often get a question on accessing data from client applications when they are new to this model of development. The question is, “Why can’t we use data access technologies like ADO.NET or Entity Framework directly in the app?”

This question arises due to lack of understanding of the architecture. If you look at the above figure, it is quite clear that the data resides on a remote server to which the device can contact using network. It is important to note that the database cannot be directly accessible from any other device on the network. So, there has to be an accessible layer between the database and the application. This layer is service. The service has to be hosted at a place that has permissions to perform required operations on the database.

Since database is not accessible directly, there is no point in supporting use of database APIs in such applications.

Happy coding!

Wednesday, 10 July 2013

Book Review - SignalR: Real-time Application Development

Over past few days, I was reading the book SignalR: Real-time Application Development, authored by Einar Ingebrigtsen and published by PaktPub. It is a nice, quick and effective read on SignalR. If you are looking for a simple guide to get you up to speed with the technology, then this book is a right choice.


The author did a nice job by keeping it very simple and yet covering what someone needs to know to start working on a project based on SignalR. All chapters are hands-on based with every step explained in detail. Because of this, it is extremely easy to follow the concepts and keep coding the examples at the same time.

First chapter of the book starts with stories on old terminal systems and discusses till rich clients and how they are better than any of the older client type. Immediately, the author jumps to web development, how it evolved over the years and what is expected out of web today. Here, it discusses what problems are solved by SignalR and why it is necessary to learn this technology.



After introducing the technology, the author dives into technical details of SignalR and discusses the underlying concepts in different chapters. The chapters cover following:

  • Creating server components using Persistent connections and Hubs and consuming them in Web and .NET clients
  • Creating groups on server and maintaining clients in the groups
  • Maintaining state
  • Securing hubs and applying authentication, authorization on Hub’s methods
  • Scaling out across multiple servers using different techniques
  • Monitoring traffic using tools like Fiddler
  • Hosting outside a web application using OWIN
  • Using SignalR in Windows Store applications

I hope you enjoy reading this 124-page quick read on SignalR as much as I did.

Happy coding!

Sunday, 23 June 2013

Unit Testing AngularJS Controller Using QUnit and Sinon


Angular JS is known for and is becoming increasingly popular due to its nature of testability. Angular’s in-the- box abstractions make any amount of code easily testable. Code written using Angular JS can be tested using any JavaScript unit testing framework out there, may it be QUnit, Jasmine, Mocha or some other library.

In an older post, we wrote unit tests for the AngularShoppingCart application using Jasmine. In this post, we will discuss on unit testing Angular JS’ controller using QUnit and Sinon.

If you haven’t followed earlier posts, take a look at the code on GitHub.

QUnit, Sinon and setting up

QUnit is a JavaScript unit testing framework developed by jQuery team. It is used in the projects like jQuery, jQuery UI, jQUery Mobile. QUnit is a very simple and generic framework that can be used to test any piece of JavaScript code. Unlike Jasmine, QUnit doesn’t have built-in support for creating spies.

Sinon is a JavaScript library that makes the process of creating spies, mocks and stubs easier. It doesn’t depend on any other JavaScript library and easily integrates with any JavaScript unit test framework. Official site has a nice API documentation covering different features of the library.

QUnit tests run on an HTML page. We need to add references to following files in the page:

  1. QUnit library
  2. QUnit style sheet
  3. Sinon library
  4. Source files of the scripts to be tested
  5. File containing unit tests for above source
  6. Any other library (like jQuery, jQuery UI, Angular) on which the source depends

As we will be testing code written using Angular JS, we should include angular-mocks.js library, which has mock services to replace some of the most commonly used services.

Following is the HTML page to run QUnit tests:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>QUnit Test Runner</title>
    
    <!-- QUnit stylesheet -->
    <link href="../../Styles/qunit-1.11.0.css" rel="stylesheet" type="text/css" />
    
    <!-- QUnit for testing and Sinon for test spies, mocks and stubs -->
    <script src="../../Scripts/qunit-1.11.0.js" type="text/javascript"></script>
    <script src="../../Scripts/sinon-1.7.3.js" type="text/javascript"></script>
    
    <!-- JavaScript libraries on which source depends -->
    <script src="../../Scripts/angular.js" type="text/javascript"></script>
    <script src="../../Scripts/angular-mocks.js" type="text/javascript"></script>
    
    <!-- Script source to test and other files on which source depends -->
    <script src="../../Scripts/app/ShoppingModule.03.js" type="text/javascript"></script>
    <script src="../../Scripts/app/ShoppingCartController.03.js" type="text/javascript"></script>
    <script src="../../Scripts/app/CartCheckoutController.js" type="text/javascript"></script>
    
    <!-- Test Script -->
    <script type="text/javascript" src="ShoppingCartControllerSpec.js"></script>
    <!--<script src="CartCheckoutTestSpec.js" type="text/javascript"></script>-->
</head>
<body>
    <div id="qunit">
    </div>
    <div id="qunit-fixture">
    </div>
</body>
</html>

Specs and Suits

QUnit has a set of blocks to create modules, setup required resources, clear them after running the tests, create a test suit and a number of assertions. Following are the blocks that we will be using:

  1. module: Defines a module, which can be used to group a number of related tests. Two functions namely, setup and teardown can be added to the module to instantiate and clear the resources for unit tests
  2. test: Used to define a test spec. Accepts a name and function containing logic to be executed. The logic contains assertions to evaluate the behaviour
  3. ok: A boolean assertion, that passes when the argument returns a Boolean true
  4. equal: An assertion that compares two values and passes if they are equal. We also have notEqual assertion that passes if the values are not equal

QUnit’s API documentation page contains details of all available blocks and asserts.

Sinon Spies and Stubs

Sinon is a very rich library with a huge API and a lot of features. We need very few of them in our specs:

  1. spy: A spy can be an anonymous function or a wrap around an existing function. There are a number of ways to create and check if the spy is invoked. We will be using one of the approaches.
    sinon.spy(obj,”methodName”) – creates a spy for a method with specified name
    obj.methodName.called – to check if the method is called
    obj.methodName.restore() – to restore the original functionality of the method
  2. stub: Stubs are spied with existing behaviour. They should be used when we want a function to behave in a way we want. We will be using the following syntax to create a stub in the unit test that we are going to write in a while:
    sinon.stub(obj,”methodName”, functionName) – Replaces the function with passed name with the logic of an existing function
Unit testing ShoppingCartController

Let’s start testing the functions defined in ShoppingCartController.

Dependencies of the controller are clearly visible from the signature. As we need to inspect behaviour of the controller in isolation, we must mock these services. Following is the signature of ShoppingCartController:

function ShoppingCartCtrl($scope, $window, shoppingData, shared) {
}

As these services will be used across specs, it is better to create them globally and initialize them in setup block. Since we will not hit the actual service, we need to use some static data to make the job of testing AJAX calls easier.
var shoppingCartStaticData = [
    { "ID": 1, "Name": "Item1", "Price": 100, "Quantity": 5 },
    { "ID": 2, "Name": "Item2", "Price": 55, "Quantity": 10 },
    { "ID": 3, "Name": "Item3", "Price": 60, "Quantity": 20 },
    {"ID": 4, "Name": "Item4", "Price": 65, "Quantity": 8 }
];
 
//Mocks
var windowMock, httpBackend, _shoppingData, sharedMock;
 
//Injector
var injector;
 
//Controller
var ctrl;
 
//Scope
var ctrlScope;
 
//Data
var storedItems;


We need to create a module to initialize all of the above objects and clear them. Following is the skeleton of the module:
module(“Shopping module”, {
 setup: function(){
  //Initialize all above objects
 },
 teardown: function(){
  //Clear up objects and restore spies
 }
});

Resolving Dependencies

Unlike Jasmine, in QUnit tests we need to use injector to get the dependencies resolved. They aren’t resolved automatically. Following statement gets an instance of the injector:

injector = angular.injector(['ng', 'shopping', 'appMocks']);
First and most important dependency of the controller is the $scope service. We need to create our own scope and pass it as a parameter while creating object of the controller. Using $rootScope, it is very easy to create our own scope.
ctrlScope = injector.get('$rootScope').$new();

Second dependency is the $window service. As we are using href property of location alone, we can create a custom object with this property alone.
windowMock = { location: { href: ""} };

Third dependency shoppingData service is a wrapper to call backend data services. It used another service, $http to send AJAX requests. Angular JS team has made our job easy by creating $httpBackend, a mock for $http. $httpBackend provides a nice interface to send our own response when an AJAX request is made. In QUnit tests, a decorator statement must be added to get the object of $httpBackend. Following snippet shows it:
var appMocks = angular.module("appMocks", []);
 
appMocks.config(function ($provide) {
    $provide.decorator('$httpBackend', angular.mock.e2e.$httpBackendDecorator);
});
shoppingData service has three functions: getAllItems, addAnItem and removeItem. We need to create stubs for these functions with a call to the original function. The stubs will be used to inspect if the function is called. Following snippet demonstrates it:
httpBackend = injector.get('$httpBackend');
_shoppingData = injector.get('shoppingData');
sinon.stub(_shoppingData, "getAllItems", _shoppingData.getAllItems);
sinon.stub(_shoppingData, "addAnItem", _shoppingData.addAnItem);
sinon.stub(_shoppingData, "removeItem", _shoppingData.removeItem);

The function getAllItems sends an HTTP GET request to the service. Following statement configures a custom response on $httpBackend when Angular detects any such request:
httpBackend.expectGET('/api/shoppingCart/').respond(storedItems);

Fourth and final dependency is the shared service. Following snippet creates a mock shared service with a spy for setCartItems, the only function used in ShoppingCartCtrl:
sharedMock = injector.get('shared');
sinon.spy(sharedMock, 'setCartItems');

Now that we have all the mocks ready, let’s create an object of the controller.
ctrl = injector.get('$controller')(ShoppingCartCtrl, { $scope: ctrlScope, $window: windowMock, shoppingData: _shoppingData, shared: sharedMock });

All spies have to be restored in the teardown block as shown below:
teardown: function () {
    sharedMock.setCartItems.restore();

    _shoppingData.getAllItems.restore();
    _shoppingData.addAnItem.restore();
    _shoppingData.removeItem.restore();
 }

Testing behaviour of the controller

Note: If you have already read the post on Jasmine, you may skip rest of the post and check the code as most of the explanation remains same

On creation of the controller, it calls getAllItems function of shoppingData service to fetch details of all items. The test for this behaviour should check if the right function is called and if it sets value to the items property. Following test shows this:

 test("Should call getAllItems function on creation of controller", function () {
     ok(_shoppingData.getAllItems.called, "getAllItems is called");
     httpBackend.flush();
     notEqual(storedItems.length, 0, "Number of items loaded is not 0");
 });

Upon calling addItem function of the controller, it calls addAnItem function of shoppingData service. As it makes an HTTP post request to the service, $httpBackend should be configured to respond when it finds a post request. Test looks as follows:
 test("Should call addAnItem function of the shoppingData service", function () {
  httpBackend.expectPOST('/api/shoppingCart/', {}).respond(storedItems.push({ "Id": 5, "Name": "Item5", "Price": 70, "Quantity": 10 }));
     ctrlScope.addItem({});
     ok(_shoppingData.addAnItem.called, "addAnItem function is called");
     httpBackend.flush();
     equal(storedItems.length, 5, "New item is added to the list");
});

The function removeItem can also be tested in similar way. But, what if a request fails? The $errorMessage property of scope should be assigned with a friendly error message. A request can be forced to fail by passing a JavaScript object literal with an error status code to $httpBackend. Let’s see this in action:
 test("Should assign an error message", function () {
     httpBackend.expectDELETE('/api/shoppingCart/1').respond({ status: 500 });
      ctrlScope.removeItem(1);
 notEqual(ctrlScope.errorMessage,"","An error message is set to the variable in scope");
 });

mySortFunction is used to convert numeric value to number. We can test this function by passing a number in the form of a string and checking if it returned a number to us. We need to set the property sortExpression before calling the function.
 test("Should return a number when a number is passed in", function () {
     var item = { "Number": "123" };
     ctrlScope.sortExpression = "Number"; 
     var numVal = ctrlScope.mySortFunction(item);
     equal(typeof numVal, "number", "Value returned is a number");
 });

The totalPrice function is very easy to test, as we need to just check if it sets some value to the returned variable.
 test("Should calculate totalPrice", function () {
     ctrlScope.items = storedItems;
     notEqual(ctrlScope.totalPrice(), 0, "Total price is calculated");
 });

On click of Purchase Items link on the page, the user has to be navigated to CheckoutItems view and setCartItems function of shared service should be called to pass the items array to the second view. As we are setting navigation URL to window.location.href, for which we created a mock, the test has to check if this property is set to some value. Following test verifies these functionalities:
 test("Should set value in shared and value of href set", function () {
     ctrlScope.items = storedItems;
     ctrlScope.purchase();
     ok(sharedMock.setCartItems.called, "setCartItems function is called");
     notEqual(windowMock.location.href,"","URL of the page is modified");
 });

Now view the test runner page on browser. All the tests should be passed. I encourage you to play a bit with the code and tests and check the result of test after the changes. This way, we will get to know more about using QUnit, Sinon with Angular JS and also about unit testing.

You can download the code including unit tests from the following GitHub repo: AngularShoppingCart

Happy coding!