2017-02-17 152 views
0

我与因缘/茉莉花测试框架的角度JS应用程序的工作角度的单元测试工厂,我需要测试工厂,返回一个HTTP承诺,但它总是返回undefined使用HTTP请求

这里是我厂

angular.module('GithubUsers').factory('Users',['$http','$q',function($http,$q){ 
 
    return{ 
 
    getAllUsers:function(){ 
 
     var defered= $q.defer(); 
 
     $http({ 
 
     url:'https://api.github.com/users', 
 
     method:'GET' 
 
     }).then(function(users){ 
 
     defered.resolve(users.data); 
 
     },function(err){ 
 
     defered.reject(err); 
 
     }) 
 
     return defered.promise; 
 
    } 
 
    } 
 
}])

这里是我的测试

更新感谢您的回答我修改了代码以下,但没有我得到这个错误

可能未处理的拒绝:{“地位”:0,“配置”:{“方法”:“GET”,” transformRequest“:[null],”transformResponse“:[null],”jsonpCallbackParam“:”callback“,”url“:”https://api.github.com/users?since=1“,”headers“:{”Accept“:”application/json,text/plain,/ “},” 缓存 “:假},” 状态文本 “:”“}抛出

describe('Test Users Factory',function(){ 
 
    var $controller, 
 
    Users, 
 
    $rootScope, 
 
    $httpBackend, 
 
    $q; 
 
    beforeEach(module('GithubUsers')); 
 
    beforeEach(inject(function(_$controller_,_Users_,_$rootScope_,_$httpBackend_,_$q_){ 
 
    $controller = _$controller_; 
 
    Users = _Users_; 
 
    $rootScope= _$rootScope_; 
 
    $httpBackend=_$httpBackend_; 
 
    
 
    
 
    })) 
 
    
 
    it('should get users',function(){ 
 
    
 
    var result; 
 

 
    $httpBackend.whenGET('https://api.github.com/users?since=1').respond(function(){ 
 
     return {data:[{id:2}],status:200}; 
 
    }) 
 
    Users.getAllUsers().then(function(res){ 
 
     result = res; 
 
    }); 
 
    $httpBackend.flush(); 
 
    $rootScope.$digest() 
 
    expect(result).toBeTruthy(); 
 
    }) 
 
})

在此先感谢!

回答

1

我认为你需要传递一个函数,它返回一个数组,其中有3个项目到whenGET()。 响应()。

也许,你可以尝试这样的事:

beforeEach(angular.mock.inject(function (User, $httpBackend, $http) { 
    ... 
    this.withOKUsers = function() { 
      var i1 = new User(); 
      i1.id = 10; 
      return [200, JSON.stringify([ i1]), {}]; 
    } ... 
})); 
...  
it('should get users',function(){ 
$httpBackend 
    .whenGET('https://api.github.com/users') 
    .respond(this.withOKUsers); 

Users.getAllUsers().then(function(res){ 
    result = res; 
});  

$httpBackend.flush(); 
expect(result).not.toBeNull(); 
... 

(我更喜欢安排它()子句外规格为更好的可读性)

+0

感谢您的回复,但不幸的是它没有为我工作 –

+0

确实忘了添加flush()方法。总是在回调和期望值之间冲洗 –

+0

感谢您请检查我更新的问题 –

1

你缺少$ httpBackend.flush ();在您的测试方法调用后调用。它会调用成功/错误,然后分离并正确解析$ q的承诺。对于更多测试,我会将$ httpBackend.whenGET分别移动到每个测试用例中,以便稍后可以根据用例进行验证,但这仅仅是我个人的看法。

我发现它有点可疑,你在一个测试中混合$控制器和工厂。我建议将它们分开,并在控制器测试中检查对服务方法的调用,并在一个相关测试中自己做一个$ httpBackend的东西。

下面我粘贴你的测试与我的更正。现在对我的作品:

describe('Test Users Factory', function() { 
var Users, 
$rootScope, 
$httpBackend, 
$q; 
beforeEach(module('app.utils')); 
beforeEach(inject(function (_Users_, _$rootScope_, _$httpBackend_, _$q_) { 
    Users = _Users_; 
    $rootScope = _$rootScope_; 
    $httpBackend = _$httpBackend_; 
})); 

afterEach(function() { 
    $httpBackend.verifyNoOutstandingExpectation(); 
    $httpBackend.verifyNoOutstandingRequest(); 
}); 

it('should get users', function() { 
    var result; 

    $httpBackend.when('GET', "https://api.github.com/users").respond({ data: [{ id: 2 }], status: 200 }); 

    Users.getAllUsers().then(function (res) { 
     result = res; 
     expect(result).toBeTruthy(); 
    }); 


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

重要告示: 1)afterEach - 检查,如果没有挂起的请求,保持您的通话 2)你的网址与参数不同,因为后= 1?。但是你不把它作为你的代码中的一个参数,所以我不明白为什么你添加了这个参数。 也许考虑与url和参数串连接?

+0

非常感谢您的澄清我不知道关于'flush'功能之前,请您检查我的更新问题 –