2016-07-11 98 views
0

我對調用我的ApiService的UserService有一個簡單的測試。我使用的是第三方API SDK,所以我不能直接使用$httpBackend,但我已經設定,以便至少在目前空數據從API返回:

// ApiService mock 
beforeEach(module($provide => 
    $provide.factory("ApiService", $q => ({ 
     request:() => $q.resolve({data: {}}), 
    })) 
)); 

// Test 
describe("registerUser",() => { 
    it("registers user",() => { 
     const registerId = "registerId"; 
     $window.SDK = {credentials: {registerId}}; 

     UserService.registerUser("socialId", "email"); 
     $rootScope.$apply(); 

     expect(UserService.registerId).to.equal(registerId); 
    }); 
}); 

// Implementation 
function UserService(ApiService, $window) { 
    let service = {}; 
    service.registerUser = (socialId, email) => { 
     return ApiService.request("registerUser", {socialId, email}).then(response => { 
      service.registerId = $window.SDK.credentials.registerId; 
     }); 
    }; 
    return service; 
} 

本質上UserService電話調用SDK的ApiService。這將設置在UserService上設置的內部registerId

我正在使用$rootScope.$apply來解決這個承諾。事實上,如果我確實打電話給我,我確認registerId已被適當設置。 然而,我得到[$rootScope:infdig] 10 $digest() iterations reached. Aborting!

如果我不使用$rootScope.$apply的承諾是永遠不會解決,registerId永遠不會被設置。

是否有任何其他方式來解決承諾或模擬此API?一般來說,我該如何正確地調試從這個$rootScope.$apply引起的無限摘要循環?它似乎沒有在循環中調用registerUser

+0

用調用堆棧發佈整個錯誤消息可能會有所幫助。我沒有看到任何會哭泣'無限摘要'的部分。這個模塊($ provide => $ provide.factory ...)是不好的,Angular不喜歡'config'塊來返回任何東西。 'UserService'不是服務,不能訪問任何依賴關係,它們應該是'undefined'。我會建議Sinon進行非角度HTTP嘲弄。 – estus

+0

@estus感謝您的建議;更多的研究讓我相信,這實際上並不是代碼的一部分,而是與單獨的服務「.run」和「ui-router」有關。你有沒有使用sinon進行非角度HTTP嘲弄的例子? –

+0

@estus我也不明白你的意思是'UserService不是服務,不能訪問任何依賴關係......我沒有在測試中注入'UserService'的部分,但是我做。 –

回答

1

真正的罪犯可能位於不相關的代碼中,路由器是無限摘要中最常出現的部分。

單元測試假設一個單元與其他運動部件隔離測試。最好不要在與路由器測試無關的規格中加載與路由器相關的模塊(這同樣適用於影響整個應用的任何其他單元)。

在這種情況下一個路由模塊(例如app.router)取決於路由器模塊(ui.routerngRoute)上,並且可以僅由頂模塊(app)被加載,而不是由其它。

app.router單元本身可包含configrun塊即建立路由,並通過(在ngRouter情況$routeProvider),其被用於路由定義($routeProvider.when,等)和間諜方法嘲笑路由器提供商進行測試。

相關問題