Wednesday, 20 June 2012

Testable client side view model with knockout without any server side dependencies

After reading the blog post series looking at creating a testable application with a JavaScript by Peter Vogel which looked at setting up the server side and the client side view model using Knockout I couldn’t help but think JavaScript needs a way of doing a kind of dependency injection so it can be unit testable without the reliance on the server side.

I understand that it will have a reliance on the server side to output the tests, however this is down to the implementation of the project not a requirement of unit testing.

View model creation

The view model is setup in a very similar way to how Peter had it in his example with a couple of tweaks to allow for the “DI” to function.

var Customer = function () {
    this.CustId = ko.observable();
    this.CompanyName = ko.observable();
    this.City = ko.observable();

    var self = this;

    this.getCustomer = function (custId) {

        MyApp.Customer.getCustomer(custId, this.updateData);

    };

    this.updateData = function (data) {
        self.CustId(data.CustomerID);
        self.CompanyName(data.CompanyName);
        self.City(data.City);
    };
}

We start by setting up the properties of the view model with the Knockout observables, set a reference to it’s self to be able to reference them later (good practice with Knockout from what I can gather), a callback binding function and the first “action” function on the model; getCustomer.

The getCustomer method calls into the data service passing in the parameters it requires for the action to execute and a callback function to call on the result. This could easily be expanded so that error handling can be caught and handled by another callback function but for this we’ll keep it simple.

With the view model set, the data service contract defined and being called in the function the view model is clean and not cluttered. At this point we can take a look at the data service “interface”.

Client side data service

var MyApp = MyApp || {};
MyApp.Customer = {};
MyApp.Customer.getCustomer = function (custId, callback) { };

The data service is built up with JavaScript object notation. The first two lines is to make sure that firstly there is a “MyApp” defined and it has a “Customer” property. Then the getCustomer function is defined with the set parameters required for execution and the delegate for the callback. Doing it this way you also add it into your own applications namespace and avoid cluttering up the global name space.

Lets look at the implementations for unit testing and for the actual application implementation.

The Unit Test

The test we are trying to pass is relatively simple and still based on Peter’s from the original series.

test("Get Customer",
    function () {
        stop();
        cust = new Customer();
        cust.getCustomer("ALFKI");
        setTimeout(function () {
            equals(cust.CustId(), "ALFKI", "ID not correct");
            equals(cust.CompanyName(), "My Company", "Company not correct");
            equals(cust.City(), "Reading", "City not correct");
            start();
        },
    3000);
    })

All it is trying to do is call getCustomer and make sure the data returned is bound to the correct properties.

Data service in testing

For testing purposes the view model test requires a populated JSON object to be returned from the data service. To enable the test to pass and remove the reliance on the server side test controller I create a mock client side data service before the qunit tests are added to the page.

var MyApp = MyApp || {};
MyApp.Customer = {};
MyApp.Customer.getCustomer = function (custId, callback) {
callback({ CustomerID: custId, CompanyName: "My Company", City: "Reading" });
};

All this is doing is following the contract/interface as defined for the data service, but instead of calling into a server side action it is returning a “mock” object. At this point we have removed the need for any server side calls.

After this has been defined we can now write our unit test (as above) and test that JSON object values which are being returned are bound to the correct properties.

Application implementation

So now we’ve created a mock data service and got our unit tests passing for the view model it’s time to create the actual implementation to allow for server communication and getting actual data.

var MyApp = MyApp || {};
MyApp.Customer = {};
MyApp.Customer.getCustomer = function (custId, callback) {
    var url = "@Url.Action("CustomerById", "Home")/" + custId;
    $.getJSON(url, null, callback);
};

As you can see we follow the same pattern as before but the difference is the getCustomer body implementation. We can now call into the server action and using jQuery’s $.getJSON method retrieve some json data from a server. The callback function is passed into the $.getJSON method which will delegate what needs to be done when the data is returned.

Conclusion

So to conclude client side unit tests do not need to have reliance on server side actions to execute even if they require data to be returned from an action. Some people may argue that the unit test isn’t testing the responses back from the server and handling them correctly. To do this you could go down the test controller route and get the server side to through actual errors or you could get the mock call to throw the errors.

If you have any comments about the above please post them below or contact me on Twitter - @WestDiscGolf.

Tuesday, 19 June 2012

Asp.net MVC 4 WebAPI RC - What on earth is “Antlr3.Runtime”?!

I upgraded to the latest version of Asp.net MVC 4 at the weekend which is the newly released “RC” so thought I’d have a play and see what’s changed.

On doing File > New on a new MVC 4 / Web API project a newly clean crisp solution loads up in Visual Studio. Just out of interest I make sure it builds – can’t be too careful with these “pre-release” builds. The solution builds fine so it’s time to explorer …

I expand the project references to see what dependencies the project now has and the list is quite large. The usual suspects are there; EntityFramework, System.Web.Mvc, System.Web.Razor etc. but I’m greeted by some un-usuals.

Disclaimer: I’ll point out now I didn’t do this check on the Beta so I’m not sure if some of the following where there before.

The first one is new and expected; Newtonsoft.Json. We’ve been hearing for a while that json.net will be rolled into the final release and here it is. Nice! I’ve been using json.net for other projects for a while and it’s good.

The second two which seem out of place are “Antlr3.Runtime” and “WebGrease”. What on earth are these?

Lets look at WebGrease first …

  • It has an entry in the nuget package file with a version number etc.
  • In object browser it has some of the “Microsoft.Ajax.Utilities” namespace in.
  • The rest seems to do with css, ui etc.
  • Delete it and the app still builds and runs.

Guessing can live with that, but could remove it. What does it do?!

The other remains a mystery; “Antlr3.Runtime”.

  • No entry in the nuget packages
  • Remove it and the default app still builds
  • In object browser from the class names it looks like it does something with Tree structures?!

From doing some searching it relates to parsing grammers etc. to interpret them in your application. Why would that be shipped with asp.net mvc 4? Couldn’t find any documentation to support this so maybe it was an oversight and will be removed from the final RTM version. Will have to wait and see …

Saturday, 5 May 2012

29 to 30–Q1 Review (Feb to April)

So the first quarter has drawn to a close so lets review where I got to with the objectives I set myself …

1. Launch personal website

I achieved this quite early on in the quarter. This was a site I’d been playing with, tweaking and re-writing a number of times over the past 6+ months. I finally decided that I’d got it to a point and published it. My problem is I never seem to be completely happy with what I write and want to put it out perfect. This doesn’t work in real life, so now I’ve got my site out there and there is a platform to build on and improve instead of striving for perfection, missing it and never getting anything into the world.

2. Run competitive 10km race

On the 15th April 2012 I took part in the 10km Regency Run in Leamington Spa. I completed the course in 54mins 52 seconds. I’m proud that I did it under my target time of an hour and glad that between my wife (@lau84) and I managed to raise almost £200 for Pancreatic Cancer Action.

3. Play disc golf right handed again

Unfortunately I have missed this. I had a set back with my recovery from surgery mid Jan to March and only now I’m starting to get back into going to the gym for a workout. My running has been going quite well recently and general fitness is pretty good so I don’t think it will be much longer (fingers crossed). I have been playing left handed and competed in the Bristol Open 2012 on the last weekend of April playing lefty.

4. Sand and paint the doors and frames upstairs in house

Missed this too. Due to my shoulder recovery set back I have not been able to do this. It will be on the list for next quarter so at least by the time the kitchen is done the upstairs should be looking a bit better.

5. Blog more

This was a bit of a woolly objective, you’ve got to have one woolly objective! I’m going to say I’ve hit this as along with my objectives posts I have done a couple of posts about other stuff with the highlight being a public refactoring exercise laid down by K. Scott Allen of OdeToCode fame which was reviewed by the man himself and my code can be found on Github. Totally going to count this as achieved!

Tuesday, 10 April 2012

An answer to OdeToCode–A refactoring experiment

I was shown a blog post by @MrKevHunter on OdeToCode.com earlier today which was partial interview question / partial skills exercise to flex your brain and coding ability.

So at lunch time I forked and pulled the code down and set about the little exercise. My first attempt was exactly that a first attempt. I wasn’t overly happy with it but generally it was ok. So on the way home I decided to continue the refactoring and have come up with a solution which I’m much happier with and have pushed that up to Github.

Let me know what you think … https://github.com/WestDiscGolf/Katas

Kev’s version can be found : https://github.com/MrKevHunter/Katas

And the original (if you want a go) can be found: https://github.com/OdeToCode/Katas

Thanks for the challenge Scott!

Thursday, 22 March 2012

Help the world; help your Granny upgrade

As a web developer having to support multiple browsers can be (very) painful at times. Getting your client to agree on which browsers need to be supported for your project and ruling out older ones is a good way forward, but until we get people to upgrade and stop using older browsers then there will always be people trying to look at your site in IE6 and wondering “why does it look this bad?”

Personally that makes me sad.

Just think … you can make a difference this Easter! When you go and see your relatives (parents, grandparents, uncles, aunts etc.) this Easter weekend coming have thought for your loved ones and the offense they may see online. Remember why we celebrate Easter and while you go to church and/or sit down to eat a lovely roast dinner with your family be a loved one and click windows update and get the latest version of Internet Explorer (or download another latest version browser).

Remember, the sooner we get people not using it the sooner more people get to use websites around world the way they were designed to be used!

Help get this percentage down this Easter (at time of writing globally 7.1% / UK 1.4%) … http://www.ie6countdown.com/