使用http请求的角度单元测试工厂

时间:2017-02-17 07:20:37

标签: angularjs unit-testing karma-jasmine

我正在研究一个带有karma / Jasmine测试框架的角度js应用程序,我需要测试一个返回http promise的工厂,但它总是返回undefined

这是我的工厂



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;
    }
  }
}])




这是我的测试

更新感谢您的回答我将我的代码修改为以下内容,但没有我收到此错误

  

可能未经处理的拒绝:{&#34;状态&#34;:0,&#34;配置&#34;:{&#34;方法&#34;:&#34; GET&#34;,&#34 ; transformRequest&#34;:[空],&#34; transformResponse&#34;:[空],&#34; jsonpCallbackParam&#34;:&#34;回调&#34;&#34; URL&#34 ;: &#34; https://api.github.com/users?since=1&#34;,&#34;标题&#34;:{&#34;接受&#34;:&#34; application / json,text / plain, / < / em>&#34;},&#34;缓存&#34;:false},&#34; statusText&#34;:&#34;&#34;}抛出

&#13;
&#13;
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();
  })
})
&#13;
&#13;
&#13;

提前致谢!

2 个答案:

答案 0 :(得分: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();
...

(我更喜欢在it()子句之外安排spec以获得更好的可读性)

答案 1 :(得分:1)

您在测试方法调用后错过了 $ httpBackend.flush(); 调用。它会调用成功/错误,然后分开并正确解决$ q的承诺。对于更多测试,我会将$ httpBackend.whenGET单独移动到每个测试用例,以便稍后我可以根据用例进行验证,但这只是我个人的意见。

我觉得你在一次测试中混合一个$ controller和一个工厂有点怀疑。我建议拆分它们,在控制器测试中只检查对服务方法的调用,并在facotry测试中自己做一个$ httpBackend的东西。

下面我用我的更正粘贴你的测试。它现在适合我:

src

重要告示: 1)afterEach - 检查通话后是否还有待处理的请求 2)你的网址与参数不同?因为= 1。但是你不要在代码中将它作为参数给出,所以我不明白为什么你添加了这个参数。 也许考虑使用url和参数进行字符串连接?