1

I'm having difficulties understanding how to resolve the problem of the unit testing the controller, which makes a GET call during initialisation.

When testing the controller method, that performs the POST request, because of the initial GET call I'm getting the following error in my tests:

Error: Unexpected request: GET

The main part of the controller looks like this:

.controller('someController', function($scope, $http, $log) {

    $scope.posts = [];

    $scope.content = '';

    $scope.read = function() {

        $http.get('/read.php')

            .success(function(data) {

                $scope.posts = data;

            })

            .error(function(data, status, headers, config) {

                throw new Error('Something went wrong with reading data');

            });

    };


    $scope.read();


    $scope.write = function() {

        $http({
            method: 'POST',
            url: '/write.php',
            data: "content=" + $scope.content,
            headers: {'Content-Type': 'application/x-www-form-urlencoded'}
        })
            .success(function(data) {

                $scope.posts.push({ id : data.id, task : $scope.content })

            })
            .error(function(data, status, headers, config) {

                throw new Error('Something went wrong with writing data');

            });

    };

});

As you can see I'm calling the read() method right after its definition - so that all records are fetched from the database on page load.

I've tried the same with the .config() or other service, but obviously the result is the same.

Now - my test is as follow:

describe('someController tests', function() {


    var $scope,
        $http,
        $httpBackend,
        $log;


     beforeEach(function() {

        module('myApp');

        inject(function($rootScope, _$http_, _$httpBackend_, _$log_) {

            $scope = $rootScope.$new();
            $http = _$http_;
            $httpBackend = _$httpBackend_;
            $log = _$log_;

        });


        $httpBackend.expectGET("/mod/read.php").respond({});


    });



    it('should add new record', inject(function($controller) {

        $controller('ToDoController', {

            $scope : $scope,
            $http : $http,
            $log : $log

        });


        $scope.posts = [];

        $scope.content = 'Some content';

        $httpBackend
            .whenPOST('/write.php')
            .respond({ id : 1, content : $scope.content });


        $scope.write();        

        $httpBackend.flush();     


        expect($scope.posts.length).toBe(1);


        afterEach(function() {

            $httpBackend.verifyNoOutstandingExpectation();
            $httpBackend.verifyNoOutstandingRequest();

        });

    }));



});

Now - there are a few questions I have about this code.

  1. Is calling the method within the controller on page load considered a good practice? I know that if I used ng-init within the document to call it - this would solve all my problems, but I just don't like this approach.

  2. In the beforeEach() method of the test I'm calling:

$httpBackend.expectGET("/mod/read.php").respond({});

to reflect the call of the read() method during initialisation, but again - I'm not sure this is the right thing to do here. I know that if I remove it - the 'should add new record' test will fail with the error mentioned above.

  1. I know that afterEach() should be placed outside of the it() block, but if I do this - it will cause the same problem, but error will apply to all of the tests within this describe block. Is putting it inside of the it() block considered a bad practice / incorrect?

  2. How would I perform the read() test - if the call is already triggered in the beforeEach() loop?

  3. Lastly - what would your suggestion be to improve / rewrite the controller and the test to make sure it works its best?

I'm pretty new to the TDD - so I'm sure it's just my limited understanding of the topic, but would appreciate some constructive help.

0

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.