Reputation: 15761
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?
Upvotes: 13
Views: 6416
Reputation: 67296
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.
Upvotes: 10