问题描述
我在一个大型 Angular 应用程序上工作,最初我们通过使用 $provide 来模拟服务进行了很多测试.但是,我们现在在测试中使用了很多 Jasmine Spies,以便对服务进行存根和监视.
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'
我们真的应该为此使用 $provide,还是在某些情况下监视服务是最好的方法?
Should we really be using $provide for this or are there cases where spying on a service is the best approach?
在 Angular 测试中,他们使用间谍来监视 Jquery 我将其视为外部服务.
In the Angular Tests they use spies for spying on Jquery which I would see as an external service.
spyOn(jq.prototype, 'on');
$provide 似乎更多地用于内部服务.
$provide seems to be used more for internal services.
module(function($provide){
$provide.provider('$exceptionHandler', $ExceptionHandlerProvider);
});
还有一个 Jasmine createSpy 函数,但现在我认为 $provide 应该始终优先于它.
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.
推荐答案
根据我自己的(有限的)经验,我会说做任何方法:
From my own (limited) experience, I would say do whatever approach makes:
- 测试代码更简单/更清晰/更短
- 限制关于您的测试在内部执行的代码的假设.
- 减少其副作用(例如运行实际的 Ajax 请求)
- 在条款或运行时间方面尽可能缩短测试时间.
通常 spyOn
方法会起作用,为了完成上述操作,我想从服务/工厂中存根单个方法.如果我需要模拟整个服务/工厂,请使用 $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:
如果您正在测试一项服务,然后要从该服务中存根其他方法,您必须使用
spyOn
为了确保稍后不会在被测代码中引入额外的依赖项,$provide
增加了一些保护.说,如果你想确保 ServiceA
只需要 ServiceB
中的 myMethod
,那么 $provide
我认为会是走的路,好像 ServiceA
在测试期间从 ServiceB
调用任何未定义的方法,都会引发错误.
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() {}
});
如果你想模拟一个返回函数的工厂,那么:
If you want to mock a factory that returns a function, so:
app.factory('myFactory', function() {
return function(option) {
// Do something here
}
});
用作:
myFactory(option);
然后验证某些代码调用 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
,然后仍然涉及间谍.在前面的示例中,如果您想验证工厂是否使用选项调用,您可能必须:
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);
然后在适当的点进行测试:
And then in the test at the appropriate point:
expect(myFactorySpy).toHaveBeenCalledWith(option);
这篇关于我什么时候应该在我的 Angular JS 单元测试中使用 $provide 和 Jasmine Spies的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!