• No se han encontrado resultados

$httpBackend and karma. Node REST testing with Mocha

In Lesson 5, we implemented a node REST server to perform CRUD operations for device data.

We have not yet hooked our server to mongodb, we will do that once we completely understand and unit test existing code base. This is all about Testing, Testing & more Testing. Client side testing using Karma & Server Side Node.js REST API testing using Mocha

Our existing unit test cases handle static data being returned by the services. Since we have refactored our code to use $resource & $http, our unit test cases need to be refactored to utilize _$httpBackend_ which is a mock API provided by angularjs. Understanding $httpBackend takes a while and getting used to. The general steps in testing controllers using httpBackend are:

1. Inject _$httpBackend_

2. Use expectGet, expectPOST & expectPUT & respond API to implement mock backend behavior

3. Run methods under test & verify results

4. _$httpBackend_.flush() to flush pending requests on demand Testing Controllers

Injecting _$httpBackend_ into the tests:

it('listDeviceController check for devices in the model',

inject(function(_$httpBackend_, $rootScope, $controller, Devices) { var scope = $rootScope.$new();

var mockBackend = _$httpBackend_;

Implementing Mock Backend behavior:

mockBackend.expectGET('http://localhost:3000/devices').

respond([{id:0, name: "iphone", assetTag:"a23456", owner:"dev", desc:"iOS4.2"}]);

expectGET specifies the request expectation & respond implements the mock response Run methods under test

controllerSpec.js: var ctrl = $controller('deviceListController', {$scope: scope}, Devices);

This creates the deviceListController. In the controller the following statement "$scope.devices = Devices.query()" does a query using the Devices service. Essentially, it makes a http GET request. This is intercepted by the ngMock angularjs module & its response is provided to the controller.

Flush the response manually mockBackend.flush();

Test the conditions

expect(scope.devices).toEqualData([{id:0, name: "iphone", assetTag:"a23456", owner:"dev", desc:"iOS4.2"}]);

Here is the code for controller CRUD testing with ngMock httpBackend:

--

/* jasmine specs for controllers go here

*/

/* Define all the services and

controllers module, so they are

accessable in your it's

return ler check for devices in the model',

mockBackend.flush();

// check the number of devices

owner:"dev", er should return correct http response in the model after controller.add',

$location, Devices) { var scope = actual add effected the devices list

//expect(Devices.quer y().length).toEqual(8

); devices in the model',

// testing for update flag

view rawcontrollerSpec.js hosted with ❤ by GitHub

--

Testing Services

Testing services is fairly straightforward. We are mainly ensuring that the services send the right http requests to the backend & expect the right responses.

--

/* jasmine specs for services go here */

describe('service', function() {

beforeEach(function(){

module('cotd.services');

module('ngResource');

});

describe('version', function() {

describe('Devices', function() { kend_, Devices) {

var mockBackend =

mockBackend.flush();

kend_, Devices) {

var item = {id:7, name: "iphone",

assetTag:"a23456", owner:"dev",

desc:"iOS4.2"};

mockBackend.flush();

kend_, Devices) {

var mockBackend = device name test

var item = {id:0,

});

});

view rawservicesSpec.js hosted with ❤ by GitHub --

Trouble-shooting:

Error: Unknown provider: $resourceProvider <- devices="" div="" resource="">

ngResource is not part of angularjs core. So, you have to include it specifically in your test specs, like so:

describe('service', function() { beforeEach(function(){

module('cotd.services');

module('ngResource');

});

Testing the server - Node REST service testing using Mocha, Chai &supertest Now that we have extensively implemented client side unit testing specs, the focus naturally turns to testing the server side. After reviewing a bunch of server side testing frameworks, i think Mocha provides for a better suite since it allows for BDD a.k.a jasmine style syntax. This allows us to keep the testing constructs fairly consistent between client & server. Lets implement hands on mocha testing for our server.

We can accomplish Server side REST based testing easily by combining 3 frameworks Mocha, Chai & SuperTest. They play well nicely and makes it easier to write Node Based REST tests.

Step 1: is to add mocha, Chai & supertest to package.json {

"name": "cotd-server",

"description": "cotd backend", "version": "0.0.1",

"private": "true", "dependencies": { "express": "3.2.2", "cors": "*"

},

"devDependencies":{

"mocha": "*", "chai": "*", "supertest": "*"

},

"scripts":{

"test": "mocha"

} }

Step 2: export the express app as a module in server.js. This is for Mocha to test the server functionality without running the server first.

module.exports = app;

Step 3: create a test directory in your server folder and Create a new file for the test spec called test-devicesRest.js. Require mocha, chai & supertest in your test spec.

var chai = require('chai'), express = require('express'), request = require('supertest');

var app = require('../server');

var expect = chai.expect;

Step 4: writing a GET test

describe('GET /devices', function(){

it('should return 200 and JSON with valid keys', function(done){

request(app) .get('/devices')

.end(function(err, res){

//validate the keys in the response JSON matches, we dont care about the values expect(res.status).to.equal(200);

expect(res.body[0]).to.have.keys(['id', 'name', 'assetTag', 'owner', 'desc']);

done();

});

});

});

Step 5: creating a simple Makefile to run our test using Mocha. running make test on the command line should run mocha. It looks for the test directory and executes test specs within it.

REPORTER = list

#REPORTER = dot

test:

@./node_modules/.bin/mocha \ --reporter $(REPORTER) test-w:

@./node_modules/.bin/mocha \ --reporter $(REPORTER) \ --growl \

--watch

.PHONY: test

Step 6: Write other tests. Here is a complete source code for our REST tests -- return 200 and JSON with valid keys', matches, we dont care about the values

return 200 and JSON with valid keys', matches, we dont care about the values

it('should return 200 and status JSON have valid status', matches, we dont care about the values return 200 and status JSON have valid status',

.end(function(err matches, we dont care about the values return 200 and status JSON have valid status', matches, we dont care about the values

view rawtest-devicesREST.js hosted with ❤ by GitHub

--

Documento similar