在茉莉花单元测试

时间:2016-10-04 13:23:56

标签: javascript angularjs unit-testing karma-jasmine provider

我在我的app.js中使用自定义提供程序进行后端调用,然后在控制器中注入该提供程序并获得promise结果(我这样做是因为在每个控制器中调用getLoggedUser我只是从提供程序获得结果)和而不是做10个电话,例如我将在提供者中只做一个)。但我无法测试此提供程序$ get方法并且测试失败,因为从未进行后端调用。

我收到错误:

Error: Unexpected request: GET https://localhost:8443/user/current

app.js

 angular.module('app', [
            ...
        ])
        .config(config)
        .run(run)
        .controller('MainCtrl', MainCtrl)
        .value('version', '1.1.0')
        .provider('userProvider', function(){

            this.$get = ['AuthenticationService',
                function(AuthenticationService) {
                    return AuthenticationService.getLoggedUser();
                }];
        });

TEST

/* jshint undef:false*/
(function() {
    'use strict';

    describe('ListingController', function() {
        var listingController, rootScope, scope, q, mockAuthenticationService, $httpBackend, service;
        var provider = {};
        var mockCurrentUser = {
            id: 1782,
            name: "One, Coordinator",
            roleId: [
                3, 10
            ],
            eauthId: "coodinator1"
        };

        beforeEach(module('app'));
        beforeEach(module('listing'));
        beforeEach(function () {
            module(function (userProviderProvider) {
                provider = userProviderProvider;
            });
        });
        beforeEach(inject(function($rootScope, $controller, $q, _$httpBackend_, _AuthenticationService_, userProvider, $injector) {
            rootScope = $rootScope;
            scope = rootScope.$new();
            $httpBackend = _$httpBackend_;
            q = $q;
            mockAuthenticationService = _AuthenticationService_;
           // provider = userProvider;
            service = $injector.invoke(provider.$get);

            rootScope.$digest();

            listingController = $controller('ListingController', {
                $scope : scope,
                mockAuthenticationService : _AuthenticationService_
            });
        }));
        describe('getLogged user and init',function(){
            it("should call getLogged function", function() {
                listingController.getLoggedUser();

                rootScope.$digest();

                expect(service).toHaveBeenCalled();
            });
        });
    });
})();

控制器

function getLoggedUser() {
            userProvider.then(function (data){
               // Here I am getting result from back end call from provider     which is good
        });

如果我在提供者中做出类似的事情:

this.$get = function (AuthenticationService) {
                return {
                    loggedUser : function() {
                        return AuthenticationService.getLoggedUser();
                    }
                }
            }

然后我可以在测试中做出类似的事情:

 spyOn(provider , 'loggedUser').and.callFake(function() {
                var deferred = q.defer();
                deferred.resolve(mockCurrentUser);
                return deferred.promise;
            });

并且这将工作测试将通过,但是当我使用userProvider.loggedUser()时,在每个控件中使用这种方法。然后它将进行额外的后端调用,并且只有一次后端调用将进行。

Ceylan更新

如果我喜欢你建议调用服务,并且在方法调用getLoggedUser来自另一个服务,每次都会进行额外的调用...而不仅仅是像我没有功能的那样。

.provider('userProvider', function(){
            return {
                $get: function(AuthenticationService) {
                    return new userService(AuthenticationService);
                }
            }
        });

服务

   function userService(AuthenticationService) {
        this.getLoggedUser  = function() {
           return  AuthenticationService.getLoggedUser();
        }
    }

1 个答案:

答案 0 :(得分:0)

这是基本结构:

$httpBackend.when('GET', 'localhost:8443/user/current').respond(200, /*optional response callback function*/); 
$httpBackend.expect('GET', 'localhost:8443/user/current');

//here goes the function that makes the actual http request

$httpBackend.flush();

请务必定义您的httpBackend var - var httpBackend = $httpBackend;

而且为了检查服务是否已被调用,您必须使用间谍。

spyOn(service, 'method').and.callThrough();

//here goes the function that calls the service

expect(service.method).toHaveBeenCalled();

您将上面的两个块组合在一起,您应该能够达到您想要的效果。

describe('something',function(){
            it("should do something", function() {

                spyOn(service, 'method').and.callThrough();

                $httpBackend.when('GET', 'localhost:8443/user/current').respond(200,/*optional response callback function*/); 
                $httpBackend.expect('GET', 'localhost:8443/user/current');

                //call the function that makes http request and calls your service

                rootScope.$digest();
                $httpBackend.flush();

                expect(service.method).toHaveBeenCalled();
            });
        });

关于您的服务:

function myService(){
    var svc = this;

    svc.myMethod = function(){
         return someDataOrPromise;
    }
}