Leo D Leo D - 8 months ago 26
AngularJS Question

how is angular mock's httpBackend passed implicitly to the $controller service in tests?

This spec passes, even though it looks like it should fail. (the code is from a book on angular and rails)

here is the angular app:

var app = angular.module('customers',[]);

["$scope", "$http", function($scope, $http) {
var page = 0;
$scope.customers = [];
$scope.search = function (searchTerm) {
if (searchTerm.length < 3) {
{ "params": { "keywords": searchTerm, "page": page } }
).then(function(response) {
$scope.customers = response.data;
},function(response) {
alert("There was a problem: " + response.status);

and, here is the Jasmine spec:

describe("Error Handling", function () {
var scope = null,
controller = null,
httpBackend = null;
beforeEach(inject(function ($controller, $rootScope, $httpBackend) {
scope = $rootScope.$new();
httpBackend = $httpBackend;
controller = $controller("CustomerSearchController", {
$scope: scope
beforeEach(function () {
httpBackend.when('GET', '/customers.json?keywords=bob&page=0').respond(500, 'Internal Server Error');
spyOn(window, "alert");
it("alerts the user on an error", function() {
"There was a problem: 500");


I don't understand how the controller is ever getting access to the $httpBackend service, injected into the anonymous function passed to inject in the beforeEach method. The $scope service is passed in, but httpBackend isn't.


$controller doesn't depend on $httpBackend service, $httpBackend isn't passed to it.

$http depends on $httpBackend (hence the name). $httpBackend is overridden in ngMock with mocked implementation and used by $http instead of the original $httpBackend (which isn't intended for direct use).