Saturday, April 19, 2014

Unit testing with sinon.js

During the unit testing of javaScript project, I came to know about sinon.js, I have not fully explored about this, however want to share some basics on this. So

What is Sinon.js?

Sinon.js is moking framework, which makes your test automate. The framework is made by javascript and it  has lots of feature like:- spy, stub, fakeTimer, fakeXhr and fakeServer. Later in this article, I'll describe about some of them.

Why we need Sinon.js?

You definetly want to make your unit test automate as much as you can. Making test automate means it does not depend over other test. The test will be performed alone for result pass or fail. During the unit test at some point you need to external resource for your testing, like you need to validate to response of ajax request. Or you want to validate the reponse which is came from server and you may need to test callback function. For that you need mock external resoruce, Eg:- fake server which does response your data , fake xhr which does response your request.

So basically sinon.js makes test is easy, maintainable and automate. Lest have some explore about it's feature.

Spy
Spy is a function that stores the arugments, it's calls, returned value, Through the spy you may know, how your function is working in your system, like how many times it's invoked, with which arguments its invoked. Lets take a look example how its worked.

For testig I am using qUnit framework

function add(a, b){
    alert(a + b);
}

test("Fake server is working", function () {
    var callback = this.spy(add);
    callback(10, 20);
    ok(callback.calledOnce);
    ok(callback.calledWith(10, 20), 'called with arugments');

});

First test is passed because callback() is invoked only once
Second test is passed because callback is invoked with 10, 20 arugments.

Stub
Stubs are like spies with predefined behaviours, which means you can use stub when you want to force the function/method to think the way you want. It can use all the api of spies. When you don't want to invoke direct function/method for testing, at that time you can use stubs,

Here is the simple example.
test("Fake server is working", function () {
    var callback = sinon.stub();
    callback.withArgs(42).returns(52);
    alert(callback(42));
    equal(callback(42), 52);
});

Fake server
You can create the fake server to response the data of request to server from your browser, and you can validate that resopnsed data.

Here how you can create fake server.
test("data from server", function () {
   var server = this.sandbox.useFakeServer();
    server.respondWith("GET", "/mytest",
  [200, { "Content-Type": "application/json" },
      '[{ "id": "52", "name": "Rock" }]']);
var callback = this.spy();
$.ajax({
url: "/mytest",
success: callback
        });

server.respond();
equal(server.requests.length, 1, "server request length");
ok(callback.called, "spy called once"); //failed
ok(callback.calledWith([{ id: "52", name: "Rock" }]));       //failed
});

Here we are calling the ajax function, and fake server is responding expected data.
By calledWith() method, we are cheking the relative paramters are passing on succesfull callback function. Here is  LIVE DEMO

Ofcourse I will update this article when will grab more about this topic.

Unit testing with javascript

UNIT TESTING

Well, I wrote some unit test for my project before six months, After that, I had left it and I had been working on the code without unit testing, I realized it's really hard to maintain the code without unit testing, Lots of time I am consuming for manual testing and maintain the code as it's complexity is increasing , So I want to make my code very maintainable, modularize with automate testing by using unit test.

So in this context I want to write some basic points about unit testing,

Why we used unit testing?
First of all unit testing means you have to test each unit of your code, which means your code would be very modularize, for write unit testing you need to put your code into particular function, and the function/method would be tested, we expect to do particular action by that function.

Whatever problem will be occured in your application, you would know on which function/method it's affecting.
You can make changes code without worry about it's bad effect into code because after changes the code you can run all the test at once and can see it's effect on partcular part of the code. You can fix these issue by working on particular code if there is any.

I am using the qUnit testing framework for unit testing of my application, which is very simple to use, It has various assertion.

Main asserstion

Check for for boolean(true, false) value
ok(true);
This assertion is passed when the condition is true.

Check for value equalness
equal(fval, sval) 
This assertion is passed when fval and sval are true, fails if these are not equal

Check equalness of value and data type.
deepEqual(1, "1");
This assertion does check it's data type also, above test would be failed.

And also it is used to compare the object like,
deepEqual({fname:'suman'}, {fname:'suman'}); 
The above assertion would be passed.

When you need to do test asynchronous function then you can use asyncTest(), For example you have a replay() function which is executed for 2 seconds. You can write the code for testing like this.

asynchTest("testing for replay", function (){
    replay();
    setTimeout(
    function (){
//this lastId is last executed id from replay();
equal(lastid, 20, the last id should be 20);
}, 
2100
    );
});

Here we invoked the replay() function, after execute this function with 2 seconds, the value of lastId should be 20, so we would check this value by running test after 2.1(2100) seconds.

As I will grip more about this will update the article.