dimanche 10 juillet 2016

Jasmine: impossible to test asynchronous requests in .run block (AngularJS)

How can I test like:

angular.module("myApp", ['ui.router', 'chart.js'])
        .run(run);

    run.$inject = [
        '$rootScope',
        '$http'
    ];

in run() I receive data from external api, processed and added to the $rootScope. In controllers I work witch $rootScope.

function run(
        $rootScope: RootScope,
        $http: ng.IHttpService
    ): any {

        $rootScope.data1 = [];
        $rootScope.data2 = [];
        $rootScope.data3 = [];
        $rootScope.loading = true;

        var goNextData1:boolean = false,
            nextData1Page:string = 'http://...',
            goNextData2:boolean = false,
            nextData2Page:string = 'http://...',
            helpData:any = {
                data1: {},
                data2: {}
            };

        function getData1Source(goNextData1, nextData1Page):any {
            $http.get(nextData1Page)
                .then(function(res:any) {

                    for (var i = 0; res.data.results.length > i; i++) {
                        var data = res.data.results[i],
                            indexData = $rootScope.data1.length;
                        $rootScope.data1.push(
                            {
                                id: ++indexData,
                                name: data.name,
                                url: data.url
                            }
                        );
                    }

                    if(res.data.next)
                    {
                        goNextData1 = true;
                        nextData1Page = res.data.next;

                        getData1Source(goNextData1, nextData1Page);
                    }
                    else
                    {
                        goNextData1 = false;
                        getData2Source(goNextData2, nextData2Page);
                    }
                });
        }

        function getData2Source(goNextData2, nextData2Page): any {
            $http.get(nextData2Page)
                .then(function(res:any) {

                    for (var i = 0; res.data.results.length > i; i++) {
                        ...
                    }

                    if(res.data.next)
                    {
                        goNextData2 = true;
                        nextData2Page = res.data.next;
                        getData2Source(goNextData2, nextData2Page);
                    }
                    else
                    {
                        goNextData2 = false;
                        preparationData();
                        ...
                    }
                });
        }

        function preparationData(): any {
            for (var i = 0; $rootScope.data1.length > i; i++) {
              ...
            }

            $rootScope.loading = false;
        }

        getData1Source(goNextData1, nextData1Page);
    }

This app is good work, but I have write unit-test. Unit-test should emulate the response from an external server, and I have to get in $rootScope processed data.

var mockScope, backend;

beforeEach(module('myApp'));

beforeEach(inject(function($rootScope, $httpBackend) {
    $httpBackend
        .expect('http://...')
        .respond ({
            "count": 3,
            "next": null,
            "previous": null,
            "results": [
                {
                    "name": "Test User 1",
                    "url": "http://..."
                },
                {
                    "name": "Test User 2",
                    "url": "http://..."
                },
                {
                    "name": "Test User 3",
                    "url": "http://..."
                }
            ]
        });

    $httpBackend
        .expect('http://...')
        .respond ({
            "count": 3,
            "next": null,
            "previous": null,
            "results": [
              {
                  "name": "Test User 1",
                  "url": "http://..."
              },
              {
                  "name": "Test User 2",
                  "url": "http://..."
              },
              {
                  "name": "Test User 3",
                  "url": "http://..."
              }
            ]
        });
}));

beforeEach(angular.mock.inject(function ($rootScope, $http) {
    mockScope = $rootScope.$new();
}));

describe('Test', function() {
    it('Should get result in $rootScope',
        inject(function($rootScope, $httpBackend) {
            runs(function () {
                console.log($rootScope);
            });

            $httpBackend.flush();
        }));
}); 

Please help me write this test. Thank you!

Aucun commentaire:

Enregistrer un commentaire