什么时候我应该在我的Angular JS Unit测试中使用$ provide和Jasmine Spies

时间:2014-04-08 19:50:28

标签: javascript angularjs unit-testing jasmine

我在一个大型的Angular App上工作,最初我们通过使用$ provide来模拟服务,完成了很多测试。然而,我们现在在测试中有很多Jasmine Spies,以便对服务进行存根和间谍。

spyOn(myService, 'myMethod').andReturn 'myValue'

我们是否真的应该使用$提供此服务,或者是否存在监视服务的最佳方法?

在角度测试中,他们使用spying on Jquery的间谍,我将其视为外部服务。

spyOn(jq.prototype, 'on');

$provide似乎更多地用于内部服务。

  module(function($provide){
    $provide.provider('$exceptionHandler', $ExceptionHandlerProvider);
  });

还有一个Jasmine createSpy函数,但现在我认为$ provide应该始终优先于它。

任何见解或帮助都将受到赞赏。

1 个答案:

答案 0 :(得分:8)

从我自己的(有限的)经验来看,我会说做任何方法:

  • 测试代码更简单/更清晰/更短
  • 限制内部测试代码的假设。
  • 减少其副作用(如运行实际的Ajax请求)
  • 在测试或运行时间内尽可能缩短测试时间。

通常spyOn方法有效,为了做到这一点,我想从服务/工厂中存根一个方法。如果我需要模拟整个服务/工厂,请使用$provide

需要考虑一个或另一个特定情况:

  • 如果您正在测试服务,那么要从该服务中存根其他方法,您必须使用spyOn

  • 为了确保以后未在测试代码中引入额外的依赖关系,$provide增加了更多的保护。比如说,如果你想确保ServiceA只需要myMethod中的ServiceB,那么$provide我认为这样就好了,就好像ServiceA一样在测试过程中来自ServiceB的任何未定义方法,都会引发错误。

    $provide.provider('ServiceB', {
        myMethod: function() {}
    });
    
  • 如果要模拟返回函数的工厂,那么:

    app.factory('myFactory', function() {
      return function(option) {
        // Do something here
      }
    });
    

    用作:

    myFactory(option);
    

    然后验证某些代码调用myFactory(option)我认为没有其他办法可以使用$provide来模拟工厂。

顺便说一下,它们不是互相排斥的选择。您可以使用$provide,然后仍然有间谍参与。在前面的示例中,如果要验证使用选项调用工厂,则可能必须:

var myFactorySpy = jasmine.createSpy();
$provide.provider('myFactory', myFactorySpy);

然后在适当的时候进行测试:

expect(myFactorySpy).toHaveBeenCalledWith(option);