2016-09-07 38 views
0

我正在測試使用其他服務進行API調用的服務,我們稱之爲數據服務。數據服務在其他地方進行了測試,因此我用一個包含空函數的簡單實現抽象出它;我通過延遲對象和Jasmine的spyOn語法返回數據。

我用這種方法發現的問題是數據返回時,它不能立即在調用對象上使用,就像我使用$ httpBackend一樣。意識到我可以使用$ httpBackend,但是我想知道在這種方法中是否遺漏了一些東西(簡單的或其他的)。

的代碼,我想測試

示例部分:

storeTheData = dataService.getSomeData(); 
storeTheData.$promise.then(function(data) { 

    /*this would work*/ 
    console.log(data); 

    /*but this would not, when testing using $q*/ 
    _.forEach(storeTheData, function(storedData) { 
     /*do something with each object returned*/ 
    }); 
}); 

作爲一個方面說明,我不認爲這種情況是由... promise.then $另一條線路上幫助,但理想情況下,我不會改變測試的代碼(我提供測試覆蓋寫入前一陣子的東西......)

例子:

beforeEach(
    ... 
    dataService = { 
     getSomeData: function() { } 
    }; 
    getSomeDataDeferred = $q.defer(); 
    spyOn(dataService, "getSomeData").and.returnValue({$promise: getSomeDataDeferred.promise}); 
    ... 
); 

it(... 
    getSomeDataDeferred.resolve([{obj: "obj1"}, {obj: "obj2"}]); 
    $scope.$apply(); 
    ... 
); 

通過上述測試,操作檯。日誌(數據)會可以測試,因爲數據可以通過傳遞到.then()中來訪問。但數據不會立即從storeTheData獲得,因此storeTheData [0] .obj將不確定。在調試,我可以看到數據,如果我通過storeTheData附加到storeTheData的承諾,通過storeTheData。$$ state.value

就像我說的,我知道我可以使用$ httpBackend來代替,但有沒有辦法用$ q 做這個,不用更改被測代碼?

回答

0

我還沒有找到一種方法來做到這一點與$ q.resolve,但我確實有一個解決方案,不涉及使用數據服務或更改被測試的代碼。這一點很好,因爲我想避免的主要事情是測試數據服務的副作用並更改代碼。

我的解決辦法是通過$注射器創建$資源對象...

$resource = $inject.get("$resource"); 

...然後返回,在我基本實現了數據業務。這意味着我可以使用$ httpBackend來響應對不依賴於數據服務定義保持一致的端點的請求。

dataService = { 
    getSomeData: function() { 
     /* new code starts here */ 
     var resource = $resource(null, null, { 
      get: { 
       method: "GET", 
       isArray: true, 
       url: "/getSomeData" 
      } 
     }); 

     return resource.get(); 
     /* new code ends here */ 
    } 
}; 
... 
$httpBackend.when("GET", "/getSomeData").respond(...;