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

Ast*_*sta 10 javascript unit-testing jasmine angularjs

我在一个大型Angular应用程序上工作,最初我们通过使用$ provide来模拟服务来完成我们的大量测试.然而,我们现在在我们的测试中有很多Jasmine Spies来存储和监视服务.

spyOn(myService, 'myMethod').andReturn 'myValue'
Run Code Online (Sandbox Code Playgroud)

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

在Angular Tests中,他们使用间谍来监视Jquery,我将其视为外部服务.

spyOn(jq.prototype, 'on');
Run Code Online (Sandbox Code Playgroud)

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

  module(function($provide){
    $provide.provider('$exceptionHandler', $ExceptionHandlerProvider);
  });
Run Code Online (Sandbox Code Playgroud)

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

任何见解或帮助将不胜感激.

Mic*_*mza 8

根据我自己(有限的)经验,我会说做任何方法:

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

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

我想到一些特殊情况需要一个或另一个:

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

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

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

    app.factory('myFactory', function() {
      return function(option) {
        // Do something here
      }
    });
    
    Run Code Online (Sandbox Code Playgroud)

    用作:

    myFactory(option);
    
    Run Code Online (Sandbox Code Playgroud)

    然后验证一些代码调用myFactory(option)我认为没有其他选择然后$provide用来模拟工厂.

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

var myFactorySpy = jasmine.createSpy();
$provide.provider('myFactory', myFactorySpy);
Run Code Online (Sandbox Code Playgroud)

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

expect(myFactorySpy).toHaveBeenCalledWith(option);
Run Code Online (Sandbox Code Playgroud)