【问题标题】:Jasmine unit testing angular service that returns promise doesn't resolve返回承诺的茉莉花单元测试角度服务无法解决
【发布时间】:2015-04-13 21:22:00
【问题描述】:

鉴于此测试代码

it('can login', inject(function ($httpBackend,$rootScope) {
        // Set up the mock http service responses
        authRequestHandler = $httpBackend.when('POST', '/login')
            .respond({success: true, user: {email: 'david@blah.com', roles: ['user']}});
        var promise = dsAuth.authenticateUser('123', '123')

        promise.then(function (success) {
            console.log('Got login response');
            expect(success).toBe(true);
            expect(dsIdentity.isAuthenticated()).toBe(true);
            console.log(dsIdentity.currentUser);
        });
        $rootScope.$digest(); //a solution found in on SO that doesn't work
    }));

那个承诺(从身份验证服务返回)永远不会解决?如何解决这个问题? .then() 函数中的代码永远不会被调用

服务代码:

(function(angular) {
angular.module('dsApp').factory('dsAuth',
    ['$http','$q',dsAuth]);
function dsAuth($http,$q) {
    return {
        authenticateUser: function(username,password) {
            var dfd = $q.defer();
            $http.post('/login', {username: username, password: password}).then(function (resp) {
                console.log($resp);
                if (resp.data.success) {
                    var user = new atUser();
                    angular.extend(user, resp.data.user);
                    atIdentity.currentUser = user;
                    dfd.resolve(true);
                } else {
                    dfd.resolve(false);
                }
            });
            return dfd.promise;
        },
        logoutUser: function() {
            var dfd = $q.defer();
            $http.post('/logout', {logout: true}).then(function () {
                atIdentity.currentUser = undefined;
                dfd.resolve();
            });
            return dfd.promise;
        }
    };
}

})(this.angular);

【问题讨论】:

    标签: angularjs unit-testing jasmine karma-runner


    【解决方案1】:

    Jasmine 不适用于异步期望。解决这个问题的方法是使用httpBackendflush()函数。

    it('can login', inject(function ($httpBackend,$rootScope) {
            // Set up the mock http service responses
            authRequestHandler = $httpBackend.when('POST', '/login')
                .respond({success: true, user: {email: 'david@blah.com', roles: ['user']}});
            var promise = dsAuth.authenticateUser('123', '123')
            var success = false;
    
            promise.then(function (result) {
                console.log('Got login response');
                success = result;
                console.log(dsIdentity.currentUser);
            });
            $httpBackend.flush();
            expect(success).toBe(true);
            expect(dsIdentity.isAuthenticated()).toBe(true);
        }));
    

    我不太确定dsIdentity 的来源,但我想您可以在自己的代码中弄清楚这一点。模式是一样的——在闭包外创建一个变量,然后在闭包内设置值。 flush() 将导致 promise 被触发,然后你就可以开始了。

    【讨论】:

    • 谢谢一大群人没有意识到它不兼容异步
    猜你喜欢
    • 2017-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 2023-03-27
    • 2020-08-19
    • 2016-04-02
    • 1970-01-01
    相关资源
    最近更新 更多