7

I'm unable to get my unit test to work properly. I have a $scope array that starts out empty, but should be filled with an $http.get(). In the real environment, there'd be approx 15 or so objects in the array, but for my unit test I just grabbed 2. For the unit test, I have:

expect($scope.stuff.length).toBe(2);

But jasmine's error is: Expected 0 to be 2.

here's my controller.js:

$scope.stuff = [];
$scope.getStuff = function () {
    var url = site.root + 'api/stuff';
    $http.get(url)
        .success(function (data) {
            $scope.stuff = data;
        })
        .error(function(error) {
            console.log(error);
        });
};

and my controller.spec.js is:

/// <reference path="../../../scripts/angular-loader.min.js" />
/// <reference path="../../../scripts/angular.min.js" />
/// <reference path="../../../scripts/angular-mocks.js" />
/// <reference path="../../../scripts/angular-resource.js" />
/// <reference path="../../../scripts/controller.js" />
beforeEach(module('ui.router'));
beforeEach(module('ngResource'));
beforeEach(module('ngMockE2E'));
beforeEach(module('myApplication'));
var $scope;
var controller;
var httpLocalBackend;

beforeEach(inject(function ($rootScope, $controller, $injector) {
    $scope = $rootScope.$new();
    controller = $controller("StuffController", {
        $scope: $scope
    });
}));

beforeEach(inject(function ($httpBackend) {
    httpLocalBackend = $httpBackend;
}));

it('should get stuff', function () {
    var url = '/api/stuff';
    var httpResponse = [{ "stuffId": 1 }, { "stuffId": 2 }];
    httpLocalBackend.expectGET(url).respond(200, httpResponse);
    $scope.getStuff();
    expect($scope.stuff.length).toBe(2);
    //httpLocalBackend.flush();
} );

Now, obviously, I changed variable names and such since this is for work, but hopefully this is enough information for anybody to help me. I can provide more if needed. I also get a second error when uncommenting the .flush() line, but I'll get to that a bit later.

Any help is greatly appreciated and thanks in advance!

EDIT:

Finally got it working! Here's my final code:

it('should get stuff', function () {
    var url = '/api/stuff';
    var httpResponse = [{ "stuffId": 1 }, { "stuffId": 2 }];
    httpLocalBackend.expectGET(url).respond(200, httpResponse);
    $scope.getStuff();
    httpLocalBackend.flush();
    expect($scope.stuff.length).toBe(2);
} );

EDIT 2: I ran into another problem, which I think may have been the root cause of this. See Unit test failing when function called on startup

2
  • 1
    can you try putting you expect after $httpBackend.flush() ? Commented Sep 10, 2014 at 21:40
  • 1
    You need to flush it before expecting the changes. Commented Sep 10, 2014 at 21:43

1 Answer 1

7

You need to place httpLocalBackend.flush() statement before expect($scope.stuff.length).toBe(2). Once you make a request you need to flush it for the data to be available in your client code.

it('should get stuff', function () {
    var url = '/api/roles';
    var httpResponse = [{ "stuffId": 1 }, { "stuffId": 2 }];
    scope.getStuff(); //Just moved this from after expectGET
    httpLocalBackend.expectGET(url).respond(200, httpResponse);
    httpLocalBackend.flush();
    expect($scope.stuff.length).toBe(2);
} );

Try this.

Sign up to request clarification or add additional context in comments.

5 Comments

Error: Unexpected request: GET /api/stuff No more request expected
I have an example which works like this: 1) I call a function making a get request such as scope.functionThatMakesAGetRequest() 2) Then I have something like this: $httpBackend.expect('GET', '/some/url/'+data) .respond(200, {response_data: false}); 3) Then I do $httpBackend.flush();
Sorry so can you also try just putting scope.getStuff() before the expectGET? It works for me.
I got the same error still. I did change expectGET to whenGET and now the only error i'm getting is "No pending request to flush !" But i'm not sure if that's a step forward or backwards..
I changed it back to expectGET, and moved the call to the function back to after the expectGET. So, expectGET, call function, flush, expect(whatever).toBe(whatever). I'll update my question with the new code, then mark your answer as accepted, since I wouldn't have gotten it without you. Thanks so much!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.