Dominik Wiśniewski
Dominik Wiśniewski

Reputation: 11

Cant pass my test with my post http function with jasmine

I can't understand why my post function doesn't pass my jasmine test. I think that issues with $httpBackend is very poor in AngularJS documentation

This is my code:

.controller('SystemControllerNg',
    ['sweetAlertService', 'dataExchangeService', function(sweetAlertService, dataExchangeService) {

    var self = this;
    self.all_products = [];

    /*
        Get product from database
    */
    self.getProductsFromDatabase = function() {

        var success = function(response) {
            self.all_products = response.data;
        };

        var error = function(errResponse) {
            console.log('Error getting products from database');
        };

        dataExchangeService.getProducts().then(success, error);
    };
    /*
        End get product
    */

    /*
        Send product to database
    */
    self.sendProductToDatabase = function(type) {
        var success = function(response) {
            self.getProductsFromDatabase();
        };

        var error = function(errResponse) {
            console.log('Error sending product to database');
        };

        dataExchangeService.sendProduct({
            "owner": 1,
            "name": self.product_input,
            "type": true,
            "size": 0,
            //"assign_category": self.categoryName_id
            "assign_category": null
        }).then(success, error);
    };
    /*
        End send product
    */

    /*
        Functions RUNNING in the background
    */
        self.getProductsFromDatabase();
    /*
        End functions RUNNING in the background
    */
}])

.factory('dataExchangeService', ['$http', function($http) {
    return {
        getProducts: function() {
            return $http.get('/api/v1/Products/');
        },
        sendProduct: function(dataObject) {
            return $http.post('/api/v1/Products/', dataObject);
        }
    };
}]);

and tests code:

describe('Testing services in "Aplication" module', function () {
    beforeEach(module('Aplication'));

    describe('SystemControllerNg controller', function () {

        var ctrl, mockBackend;

        beforeEach(inject(function($controller, $httpBackend) {
            mockBackend = $httpBackend;

            ctrl = $controller('SystemControllerNg');
        }));

        //In this issue everything is ok
        it('it should load products from database', function() {
            expect(ctrl.all_products).toEqual([]);

            var resObj = {
                "owner": 1,
                "name": "",
                "type": true,
                "size": 0,
                "assign_category": null
            };

            mockBackend.expectGET('/api/v1/Products/')
                .respond([ resObj ]);

            mockBackend.flush();

            expect(ctrl.all_products).toEqual([ resObj ]);
        });

        it('it should send product to database', function() {
            //expect(ctrl.all_products).toEqual([]);

            var dataObject = {
                "owner": 1,
                "name": "product",
                "type": true,
                "size": 0,
                "assign_category": null
            };

            //I don't know why can't pass it :|
            mockBackend.expectPOST('/api/v1/Products/', dataObject).respond(201, {});

            mockBackend.flush();

            //expect(ctrl.all_products).toEqual([ dataObject ]);
        });

        afterEach(function() {
            mockBackend.verifyNoOutstandingExpectation();
            mockBackend.verifyNoOutstandingRequest();
        });
    });
});

First test expectGET work great, but why expectPOST doesn't? If you know why it doesn't work I will be very grateful.

This is my log console: console log

Thanks in advance.

Upvotes: 1

Views: 78

Answers (1)

MBielski
MBielski

Reputation: 6620

Two points here:

1) In your test you are not calling the controller method that would call the service that would make the POST event happen.

    it('it should send product to database', function() {
        //expect(ctrl.all_products).toEqual([]);

        var dataObject = {
            "owner": 1,
            "name": "product",
            "type": true,
            "size": 0,
            "assign_category": null
        };

        //I don't know why can't pass it :|
        mockBackend.expectPOST('/api/v1/Products/', dataObject).respond(201, {});
        //this is missing from your test
        ctrl.sendProductToDatabase();

        mockBackend.flush();
        scope.$digest();

        expect(ctrl.all_products).toEqual([ dataObject ]);
    });

2) When you test a controller that calls methods of a service, you should be mocking the service and injecting it into the controller during the test setup. Your tests for the controller should be testing what the controller does, not what the service does. Test your services independently.

Upvotes: 1

Related Questions