Sunday 11 December 2016

Test case for angular $http Post and Get

                  AngularJs -  Test case for HTTP Post and Get


If you are developing code in Angular Js then it is most likely that you write method post and get for service calls.  How about writing test cases for this methods. 

Note : Below example uses ES6 JavaScript  and Mocha-Sinon-Chai Test suit.

HTTP Get:

lets understands with example:

      getCall() {
            return this.$http.get('../api/getcall').then(res => get(res, 'data.source'));
     }


Test case :  Its simple using whenGet. whenGet is provided by httpBackend mock api which  respond with given data once flush() is called.

 describe ('getCall' , => {
    it('should resolve  with correct data', () => {
           let res;
           const data = { source: 'testData' };
           $httpBackend.whenGET(u => u === '/api/getcall').respond(data);
           const promise = service.getCall().then((r) => res = r);
           $httpBackend.flush();
           expect(res).to.deep.equal('testData');
    });
});




HTTP Post:


lets understands with example:

      getPost() {
            return this.$http.post('/api/postcall', data, {
                  headers: {
                       'Content-Type': 'application/json',
                  },
            }).then((res) => get(res, 'data.data'));
          }


Test case :  This is the reason i am writing the blog.  You can notice the difference of test case of whenGet and below one. If you pass the function inside respond method then you have to return response with status code which 200 in below case.

 describe ('postcall' , => {   
   it('should resolve with correct data', () => {
          let res;
          $httpBackend.whenPOST(u => u === '/api/postcall')
                .respond((method, '/api/postcall', data) =>  [200, { data: { key: '11' } }]);           
           service.getPost({ data: 'submitionData' }).then((r) => res = r);
           $httpBackend.flush();
           expect(res).to.eql({ key: '11' });
    });
});



Above same can be written without respond code if do not pass the above method in respond function argument (blue color one).


 describe ('postcall' , => {   
    it('should resolve with correct data', () => {
          let res;
          $httpBackend.whenPOST(u => u === '/api/postcall')
                .respond({ data: { key: '11' } });
           service.getPost({ data: 'submitionData' }).then((r) => res = r);
           $httpBackend.flush();
           expect(res).to.eql({ key: '11' });
    });
});


Above same is applicable for whenGet with/without respond code.


when :

HTTP post and get can be written with $httpBackend.when   . Just we need to pass the method name along with URL.



 describe ('postcall' , => {    
   it('should resolve with correct data', () => {
          let res;
          $httpBackend.when( 'post', u => u === '/api/postcall')
                .respond({ data: { key: '11' } });
           service.getPost({ data: 'submitionData' }).then((r) => res = r);
           $httpBackend.flush();
           expect(res).to.eql({ key: '11' });
    });
});


You can resolve call with error status. Just  by doing respond(function () { return [500]; }) in above call.

This is all possible for other HTTP verbs like Delete, Put also.

Please refer the below JSfiddle demo for the same. I have not used ES2015. Easy to understand the test cases.

http://jsfiddle.net/vippatel90/8tcn38pr/

I hope this information will be useful  for all. I understand it worth to share :)



Friday 2 December 2016

Spying on Jasmine vs Mocha + Sinon + Chai


                           Spying on Jasmine vs Mocha + Sinon  + Chai


As a UI front end developer, many of us have come across the Jasmine framework for Js test cases and Mocha Sinon with Chai assertion Library.  We know that it almost impossible to write test case without SPY functionality of any Testing Framework. Let me tell you basic difference between above two framework when you make a SPY for test case.


1. Anonymous spy : 

creates an anonymous function that records arguments, this value, exceptions and return values for all calls. It does not call actual function.

Using Jasmine:


           object.method =  jasmine.createSpy(); OR

            spyOn( object, 'method' ); (from jasmine 2.0) 

*Important : SpyOn needs method to be present on object so not actually anonymous spy while jasmnie.createSpy does not require as it assigns empty anonymous function. 

In short if your try spyOn(object, 'method') without having method available on object then you will get error stating the method to be spied upon does not exist on object.

Using Mocha chai:  


     object.method =  sinon.spy();
            
             sinon.stub( object , 'method');

*Important :  sinon.stun needs  method to be present on object so not actually anonymous spy while sinon.spy() does not require as it assigns empty anonymous function.



2. Spy with Actual function call : 

calls actual implementation and allow to record arguments, this value, exceptions and return values for all calls. 

Using Jasmine:


              spyOn( object, 'method' ).add.callThrough()

Using Mocha chai:


             sinon.spy(object , 'method');   

             (Notice the difference between sinon.spy and sinon.stub)



3. Spy with stub function call : 

assign the stub function which can receive the arguments and can return the stub data. 


Using Jasmine:


      spyOn( object, 'method' ).add.callFake( function (args) { 
                  return  value;
             });            

             for just return the value :

              spyOn( object, 'method' ).add.returnValue(true);



Using Mocha chai: 


      sinon.stub( object, 'method', function (args) {
                   retrun value;
              }); 



conclusion:


I write the test cases in both framework and above noticed 
differences helped me a lot to quick writing of the test case. Hope you can get benefit of that. Enjoy :)