1

I've just read a lot of articles about mocking $http and something is wrong with my code. I still have error: No pending request to flush !

My method from controllers.js looks similar to this (browserDebugMode, webRoot, commentsAction are global variables - it wasn't mi idea to make it global :D)

$scope.getComments = function(){   
        if (browserDebugMode) {
            $http({
                method  : "GET",
                url     : webRoot+commentsAction,
                params  : {action: "list"},
            })
                .success(function(data, status) {
                    //...
                })
                .error(function(data, status) {
                   //...
                });     
        } 
}

And now test for it:

var browserDebugMode = true;
var webRoot = "http://localhost/name";
var commentsAction = '/commentsMobile.php';

describe('myApp', function() {
var scope,
    httpBackend,
    http,
    controller;

beforeEach(angular.mock.module('myApp'));

describe('NewsDetailCtrl', function() {

    beforeEach(inject(function ($rootScope, $controller, $httpBackend, $http) {
        scope = $rootScope.$new();
        httpBackend = $httpBackend;
        http = $http;
        httpBackend.when("GET", webRoot+commentsAction).respond([{}]);
        controller = $controller('NewsDetailCtrl', {
            '$scope': scope, 'GlobalService': globalService, $http: $http
        });
    }));

    it('checks if AJAX is done', function () {
        httpBackend.expectGET(webRoot+commentsAction).respond([{}]);
        scope.getComments()
        httpBackend.flush();
    });
  });

});

And please don't ask for PHP script :) I was pushed to do it.

I just want to check if I can test $http, nothing more. I don't know what I do wrong. I tested other things in that controller and it was okay, I looked if getComments() is fired with console.log and it's fired. Something must be wrong with configuring it.

1 Answer 1

1

Your code under test and the unit tests execute in different contexts, so they will have different global objects and therefore the browserDebugMode that exists in your tests is different to the one in your actual code.

The controller should inject $window (Angular's wrapper around the window object) and then check the browserDebugMode property of that:

if ($window.browserDebugMode) {
    // actual code
}

The tests should also inject $window and then set the browserDebugMode property of that:

beforeEach(inject(function ($window) {
    $window.browserDebugMode = true;
}));

Now both the controller and tests will reference the same global object, the if condition should evaluate true, and the $http call should execute.

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

Comments

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.