問題描述
我在一個大型 Angular 應(yīng)用程序上工作,最初我們通過使用 $provide 來模擬服務(wù)進行了很多測試.但是,我們現(xiàn)在在測試中使用了很多 Jasmine Spies,以便對服務(wù)進行存根和監(jiān)視.
I work on a large Angular App and initially we done a lot of our tests by using $provide to mock services. However we now have a lot of Jasmine Spies in our tests in order to stub and spy on services.
即
spyOn(myService, 'myMethod').andReturn 'myValue'
我們真的應(yīng)該為此使用 $provide,還是在某些情況下監(jiān)視服務(wù)是最好的方法?
Should we really be using $provide for this or are there cases where spying on a service is the best approach?
在 Angular 測試中,他們使用間諜來監(jiān)視 Jquery 我將其視為外部服務(wù).
In the Angular Tests they use spies for spying on Jquery which I would see as an external service.
spyOn(jq.prototype, 'on');
$provide 似乎更多地用于內(nèi)部服務(wù).
$provide seems to be used more for internal services.
module(function($provide){
$provide.provider('$exceptionHandler', $ExceptionHandlerProvider);
});
還有一個 Jasmine createSpy 函數(shù),但現(xiàn)在我認為 $provide 應(yīng)該始終優(yōu)先于它.
There is also a Jasmine createSpy function but now I'm thinking that $provide should always take precedence over that.
對此的任何見解或幫助將不勝感激.
Any insights or help in this would be appreciated.
推薦答案
根據(jù)我自己的(有限的)經(jīng)驗,我會說做任何方法:
From my own (limited) experience, I would say do whatever approach makes:
- 測試代碼更簡單/更清晰/更短
- 限制關(guān)于您的測試在內(nèi)部執(zhí)行的代碼的假設(shè).
- 減少其副作用(例如運行實際的 Ajax 請求)
- 在條款或運行時間方面盡可能縮短測試時間.
通常 spyOn
方法會起作用,為了完成上述操作,我想從服務(wù)/工廠中存根單個方法.如果我需要模擬整個服務(wù)/工廠,請使用 $provide
.
Usually the spyOn
approach works when, in order to do the above, I would like to stub a single method from a service / factory. If I need to mock an entire service / factory, then use $provide
.
我想到了一些需要其中之一的特定情況:
A few specific cases come to mind that require one or the other:
如果您正在測試一項服務(wù),然后要從該服務(wù)中存根其他方法,您必須使用
spyOn
為了確保稍后不會在被測代碼中引入額外的依賴項,$provide
增加了一些保護.說,如果你想確保 ServiceA
只需要 ServiceB
中的 myMethod
,那么 $provide
我認為會是走的路,好像 ServiceA
在測試期間從 ServiceB
調(diào)用任何未定義的方法,都會引發(fā)錯誤.
To ensure that extra dependencies aren't introduced later in the code under test, than $provide
adds a bit more protection. Say, if you want to ensure that ServiceA
only requires myMethod
from ServiceB
, then $provide
I think would be the way to go, as if ServiceA
calls any undefined methods from ServiceB
during the test, errors would be raised.
$provide.provider('ServiceB', {
myMethod: function() {}
});
如果你想模擬一個返回函數(shù)的工廠,那么:
If you want to mock a factory that returns a function, so:
app.factory('myFactory', function() {
return function(option) {
// Do something here
}
});
用作:
myFactory(option);
然后驗證某些代碼調(diào)用 myFactory(option)
我認為沒有其他選擇然后使用 $provide
來模擬工廠.
Then to verify that some code calls myFactory(option)
I think there is no alternative then to use $provide
to mock the factory.
順便說一句,它們不是相互排斥的選項.您可以使用 $provide
,然后仍然涉及間諜.在前面的示例中,如果您想驗證工廠是否使用選項調(diào)用,您可能必須:
Just by the way, they're not mutually-exclusive options. You can use $provide
and then still have spies involved. In the previous example, if you want to verify the factory was called with an option, you might have to:
var myFactorySpy = jasmine.createSpy();
$provide.provider('myFactory', myFactorySpy);
然后在適當(dāng)?shù)狞c進行測試:
And then in the test at the appropriate point:
expect(myFactorySpy).toHaveBeenCalledWith(option);
這篇關(guān)于我什么時候應(yīng)該在我的 Angular JS 單元測試中使用 $provide 和 Jasmine Spies的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!