jeudi 4 juin 2015

Angular Unit Testing Service with multiple service calls using $q.all

Ok here is the scenario we are trying to unit test with Jasmine. We have a service defined similar to the service below:

(function () {

    'use strict';

    angular.module('mymodule')
           .service('myservice', myservice);

    myservice.$inject = ['$q', '$resource', 'progressService', 
            'myservice2', 'myservice3', 'ngDialog'];
    function myservice($q, $resource, progressService, 
            myservice2, myservice3, ngDialog) {

        var self = this;
        self.dataListSvc2 = [];
        self.dataListSvc3 = [];
        self.dataFromResource = null;
        self.myRoutine = myRoutine;

        var myResource = $resource('/someurl/webapi/GetData');

        //TRYING TO TEST THIS ROUTINE!!!
        function myRoutine(param1, param2) {

            return progressService.show($q.all([
                myResource.get({ Param1: param1 }).$promise.then(function (response) {
                    self.dataFromResource = response;
                }),
                myRoutine2(param2),
                myRoutine3(param2)
            ]));

        }

        function myRoutine2(param) {

            return myservice2.getSomeData(param).then(function (response) {
                var results = [];
                self.dataListSvc2 = [];

                response.forEach(function (item) {
                    item.AddField1 = null;
                    item.AddField2 = false;
                    results.push(item);
                });

                self.dataListSvc2 = results;
            });

        }

        function myRoutine3(param) {

            return myservice3.getSomeMoreData(param, [6])
                .then(function (response) {
                    self.dataListSvc3 = response;
                });

        }      
})();

I am trying to write a unit test for myservice.myRoutine() and not having any luck, I suspect it is due to the $q.all array of promises. Here is a test I settled on but it is not ideal and honestly I don't feel like it's testing anything of value. I have also tried "mocking" the three requests with $httpBackend with no luck as all three responses come back in an array with undefined values. I searched around SO and the web and I am only finding $q.all([]) unit tests referencing controllers but not services. If anyone has some input it would be much appreciated. Here is where I settled for the time being:

describe('My Service: ', function () {

    var $httpBackend;

    beforeEach(module('mymodule'));

    beforeEach(inject(function ($injector) {
        // Set up the mock http service responses
        $httpBackend = $injector.get('$httpBackend');
    }));

    it('Can call myroutine from myservice', inject(function (myservice) {

        //Arrange
        var expectedVal1 = 1234;
        var expectedVal2 = 1234;

        spyOn(myservice, "myRoutine");

        //Act
        myservice.myRoutine(expectedVal1, expectedVal2);

        //Assert
        expect(myservice.myRoutine).toHaveBeenCalled();

    }));
});

Aucun commentaire:

Enregistrer un commentaire