2014-10-09 68 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