I have a simple controller and the first thing I need it to do is assign a value to scope.
function TestCtrl($scope, $http) {
    $scope.listForms = 'some list';
}
The following test for the controller works as expected:
describe('Testing a controller', function() {
    var ctrl, scope, httpMock;
    beforeEach(inject(function($injector) {
        scope = $injector.get('$rootScope').$new();
        ctrl = $injector.get('$controller');
        ctrl(TestCtrl, { $scope: scope });
    }));
    it("assigns to scope", function() {
      expect(scope.listForms).toMatch("some list");
    });
});
But when I change the function to get the list from my API
function TestCtrl($scope, $http) {
  $http.get('/api/listForms').success(function(list) {
    $scope.aListOfForms = 'some list';
  });
}
and the test changes to
describe('Testing a controller', function() {
    var ctrl, scope, httpMock;
    beforeEach(inject(function($injector) {
        httpMock = $injector.get('$httpBackend');
        scope = $injector.get('$rootScope').$new();
        httpMock.when('GET', '/tactical/api/listOrderForms').respond("an order form");
        ctrl = $injector.get('$controller');
        ctrl(TestCtrl, {
            $scope: scope,
            $http: httpMock
        });
    }));
    it("gets the list from the api and assigns it to scope", function() {
      httpMock.expectGET('tactical/api/listOrderForms');
      expect(scope.orderFormList).toMatch("an order form");
      httpMock.flush();
    });
});
I get the following errors:
TypeError: 'undefined' is not a function
Expected undefined to match 'an order form'.
Error: No pending request to flush !
Does anyone know what I am doing wrong? Thanks in advance.
$http uses $httpBackend to talk to external resources. You have mocked $httpBackend, but the controller still needs to talk to it trough $https interface.
This should do it:
describe('Testing a controller', function() {
    var ctrl, scope, httpMock;
    beforeEach(inject(function($controller, $rootScope, $httpBackend) {
        httpMock = $httpBackend;
        scope = $rootScope.$new();
        httpMock.when('GET', '/tactical/api/listOrderForms').respond("an order form");
        ctrl = $controller;
        ctrl(TestCtrl, {
            $scope: scope
        });
    }));
    it("gets the list from the api and assigns it to scope", function() {
      httpMock.expectGET('tactical/api/listOrderForms');
      httpMock.flush();
      expect(scope.orderFormList).toMatch("an order form");
    });
});
                        you can't replace $http service as $httpBackend service for your controller manually.
Change
    ctrl(TestCtrl, {
        $scope: scope,
        $http: httpMock
    });
to
    ctrl(TestCtrl, {
        $scope: scope
    });
It should work.
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