I am trying to figure out how to test my AngularJS service that has a dependency on $http
.
When using $httpBackend
to mock that AJAX post (whenPOST
), does the object you post determine the response?
Here is my service and my test for example:
(function () {
"use strict"
var app = angular.module('cs');
app.service('PlateCheckService', ['$http', function ($http) {
return {
checkPlate: function (plateNumber) {
return $http.post('PlateCheck/Index', {
plateNumber: plateNumber
}).then(function (response) {
return {
message: response.data.VehicleAtl === null ? 'Clean' : 'Hot',
alertClass: response.data.VehicleAtl === null ? 'alert-success' : 'alert-danger'
}
});
}
}
}]);
}());
Tests
/// <reference path="../libs/angular-1.0.8/angular.js" />
/// <reference path="../libs/angular-1.0.8/angular-mocks.js" />
/// <reference path="../libs/jasmine-1.3.0/jasmine.js" />
/// <reference path="../app.js" />
/// <reference path="../services/plate-check-service.js" />
describe('Plate Check Service', function () {
var httpBackend,
service;
beforeEach(function () {
module('cs');
inject(function ($httpBackend, PlateCheckService) {
httpBackend = $httpBackend;
httpBackend.whenPOST('PlateCheck/Index', { plateNumber: '123456' }).respond({
response: {
message: 'Clean',
alertClass: 'alert-success'
}
});
httpBackend.whenPOST('PlateCheck/Index', { plateNumber: '123456789' }).respond({
response: {
message: 'Hot',
alertClass: 'alert-danger'
}
});
service = PlateCheckService;
});
});
it('Should return a clean plate.', function () {
var result;
service.checkPlate('123456').then(function (response) {
result = response;
});
httpBackend.flush();
expect(result.message).toBe('Clean');
expect(result.alertClass).toBe('alert-success');
});
});
Test Results
Test 'Plate Check Service:Should return a clean plate.' failed
Expected 'Hot' to be 'Clean'.
Expected 'alert-danger' to be 'alert-success'.
in D:\Code\Scripts\angular\specs\plate-check-service-specs.js (line 35)
0 passed, 1 failed, 1 total (chutzpah).
========== Total Tests: 0 passed, 1 failed, 1 total ==========
It looks like it is not taking into account the plateNumber
I am passing to the service which posts it to the server.
I would have expected this test to pass.
Does that make any sense?
Share. Unit testing is referred to as testing of smallest individual parts of an application independently. We will be looking at how to implement unit testing using Jasmine & Karma with an Angular JS application.
AngularJS is written with testability in mind, but it still requires that you do the right thing. We tried to make the right thing easy, but if you ignore these guidelines you may end up with an untestable application.
Angular Unit testing is the process of testing small and isolated pieces of code in your Angular application. This provides an added advantage to the users in the sense that they can add any new features without breaking any other part of their application.
You are using a when
instead of a expect
. $httpBackend
can run in two different modes. From the docs:
There are two ways to specify what test data should be returned as http responses by the mock backend when the code under test makes http requests:
- $httpBackend.expect - specifies a request expectation
- $httpBackend.when - specifies a backend definition
Request Expectations vs Backend Definitions Request expectations provide a way to make assertions about requests made by the application and to define responses for those requests. The test will fail if the expected requests are not made or they are made in the wrong order.
Backend definitions allow you to define a fake backend for your application which doesn't assert if a particular request was made or not, it just returns a trained response if a request is made. The test will pass whether or not the request gets made during testing.
If you change your setup to use an expectPOST
, then the mock will take the request into account.
Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With