2014-10-09 54 views
2

我想测试一个角度服务,返回一个承诺的摩卡柴,但在单元测试中调用'然后'超时。我的服务依赖于具有异步$资源请求的第二个服务。 myService.getData()应该从内部获取来自所述异步服务的数据,并将承诺传递给控制器​​,控制器在响应中调用“then”函数。这在控制器中很好用,并且在单元测试中绝对失败。摩卡/角度单位测试永远不会运行'然后'功能

服务代码:

// use: myService.getData.then(...) works beautifully in angular controllers 
getData = function(dataId) { 
    var dataPromise; 

    // get students from the api, if necessary, or from the service if already retrieved 
    // dataList is a private property of the service 
    if(!dataList) { 
     dataPromise = asyncServiceUsedByMyService.asyncMethod({...}).$promise 
      .then(
       function(response){ 


        dataList = response; 

        doSomeDataManipulation(); 

         return dataList; 
       }, 
       function(err) { 
        return err; 
       } 
      ); 
    } 
    // use the existing studentList if available 
    else { 
     dataPromise = $q.when(function(){ 
      return dataList 
     }); 
    } 

    return dataPromise; 
}; 

测试代码

describe('Service Test', function() { 
    var expect = chai.expect, 
     myService, 
     asyncServiceUsedByMyService; 


    beforeEach(function() { 

     var data, 
      asyncServiceMock; 

     data =[...]; 

     // mock the async dependency 
     asyncServiceMock = { 
      asynchMethod: function() { 
       var deferred = q.defer(); 

       deferred.resolve(data); 
       return {$promise: deferred.promise}; 
      } 
     }; 

     module('myApp'); 

     module(function($provide){ 
      $provide.value('asyncServiceUsedByMyService', asyncServiceMock); 
     }); 

     inject(function(myService, $q, asyncServiceUsedByMyService) { 
      myService = myService; 
      q = $q; 
      courseEnrollmentService = courseEnrollmentServiceMock; 
     }); 
    }); 

    // passes 
    it('should be available', function() { 
     expect(!!myService).to.equal(true); 
    }); 

    // 'then' function is never called, unit test times out 
    it('should get all items from async dependency', function(done) { 
     myService.getData().then(function(response) { 
      expect(response).to.have.property('length').that.equals(5); 
      done(); 
     }); 
    }); 

}); 

我如何得到“然后”为myService的功能,在单元测试运行,因此它会得到嘲笑的数据(应该几乎是瞬间的,因为我们没有进行实际的API调用?)。

注:我也试过“柴作为许诺的”语法,但以下似乎超时

it('should get all items from async dependency', function(done) { 
    expect(myService.getData()).to.eventually.have.property('length').that.equals(5).and.notify(done); 
}); 

回答

4

在角的承诺分辨率的消化周期,您就可以触发这个在测试中调用scope.$apply();循环。您可以阅读更多here

+0

添加范围$ apply()强制测试运行并通过或失败,但karma确实有一些错误,导致我的一些测试导致整个页面重新加载。另外(可能与重新加载有关?)我无法再调试我的测试。当我尝试在Chrome(默认因果浏览器)中调试我的Karma测试时,出现NOT FOUND(404)错误,并且我无法在Chrome开发工具中找到javascript源代码。有没有更好的方法来测试异步承诺,没有'then'和'apply',因为Karma显然不能很好地处理? – ansorensen 2014-10-20 19:10:22

+0

我一直在使用Karma,但与茉莉花和承诺从来没有问题,所以我真的不知道你的测试发生了什么。 – 2014-10-21 03:41:20