业力模拟承诺回应

karma mock promise response

我想测试以下工厂:

angular
    .module('enigma.authFactory', [])    
    .factory('authFactory', authFactory);

authFactory.$inject = ['$http'];

function authFactory($http){
    function doesUserExist(email){
        return $http.post('/doesUserExist', email)
            .success(function(data){
                if(data !== 'user exists'){
                    return false;
                } else {
                    return true;
                }
            });
    }
}

所以我写了下面的测试:

describe('Auth Service Tests', function() {
    var $httpBackend, defer, doesUserExistReqHandler;

    beforeEach(inject(function(_$httpBackend_, $injector, $q) {
        $httpBackend = _$httpBackend_; 
        defer = $q.defer();
        doesUserExistReqHandler = $httpBackend.when('POST', '/doesUserExist').respond(defer.promise);
    }));

    describe('authFactory.doesUserExist()', function() {
        it('should return true is a user exists', function() {
            user = {
                email: 'bwayne@wayneenterprise.com'
            };
            $httpBackend.whenPOST('/doesUserExist', user).respond('user exists');
            var doesUserExist = authFactory.doesUserExist(user);
            $httpBackend.flush();
            expect(doesUserExist).toEqual(true);
        });
    });
});

我检查了 authFactory.doesUserExist 函数内部,我正确地将数据集设置为 'user exists',从而将函数路由到 return true。但是在单元测试中 authFactory.doesUserExist 被设置为以下对象。

Expected Object({ $$state: Object({ status: 1, pending: undefined, value: Object({ data: Object({ $$state: Object({ status: 0 }) }), status: 200, headers: Function, config: Object({ method: 'POST', transformRequest: [ Function ], transformResponse: [ Function ], paramSerializer: Function, url: '/doesUserExist', data: Object({ email: 'bwayne@wayneenterprise.com' }), headers: Object({ Accept: 'application/json, text/plain, */*', Content-Type: 'application/json;charset=utf-8' }) }), statusText: '' }), processScheduled: false }), success: Function, error: Function }) to equal true.

我认为问题是测试没有正确解决承诺,所以我在 authFactory.doesUserExist return 为真之前设置 res 变量。

我该如何解决这个问题?

因此,需要做一些事情才能让您的代码与现有的一起工作。

这是一个演示 http://plnkr.co/edit/4GvMbPJgc0HcJcgFZ4DL?p=preview

  1. 您的服务(工厂)需要 return 一个对象。
  2. 您没有在 $http post 之后 return 做出承诺。
    • 我推荐你使用$q服务。

测试中

  1. 您需要导入您的模块。
  2. 一定要注入你的服务
  3. 您应该删除 $httpBackend.when('POST', '/doesUserExist').respond(defer.promise);,因为它没有完成任何事情,实际上它在其他 $httpBackend.whenPost.
  4. 中混淆了
  5. 您应该断言响应数据而不是承诺,因为 authFactory.doesUserExist(user) return 是一个承诺。

代码:

var doesUserExist = authFactory.doesUserExist(user)  
  .then(function (data) {
    responseData = data;
  });

$httpBackend.flush();
expect(responseData).toEqual(true);