用于AngularJS的Karma/Jasmine中的模块依赖性

Ale*_*ski 6 unit-testing mocking angularjs karma-jasmine

我正在尝试在Karma/Jasmine中为我的项目中的特定模块编写一些单元测试destination-filters.

模块清除:

angular.module('destination-filter', ['ngSanitize']);
Run Code Online (Sandbox Code Playgroud)

我的测试失败,除非我ngSanitize作为依赖项删除.据我所知,这是因为当模块被实例化时,它会尝试并引入该依赖项,但因为在我的spec.js文件中我没有声明该模块失败.

规格文件:

describe('Destination Filter Controller', function () {

  // Set the variables
  var $controller;
  var mockNgSanitize;

  beforeEach(module('destination-filter'));

  beforeEach(function() {
      module(function($provide) {
          $provide.value('ngSanitize', mockNgSanitize);
      });
  });

  beforeEach(inject(function (_$controller_) {
      $controller = _$controller_('DestinationFilterController');
  }));

  it('should expect the controller to not be null', function() {
      // Check the controller is set
      expect($controller).not.toBeNull();
  });

});
Run Code Online (Sandbox Code Playgroud)

以前,在模拟服务或函数时,该$provide方法已证明非常有用,但我不确定我在这里使用它是否正确.我假设$provide以这种方式使用不能模拟整个模块而是服务?

为了澄清,如果我...['ngSantize'])...从模块减速中删除了测试,则测试会正确实例化.我收到的错误留在了Error: [$injector:modulerr] destination-filter

br3*_*3w5 7

在测试中使用ngSanitize可以有三个选项:

  1. 将服务注入您的测试
  2. 在ngSanitize上调用方法调用
  3. 模拟整个ngSanitize服务

您选择的选项实际上取决于在您的工作代码中使用ngSanitize(而不是您的测试代码).

无论你选择哪一个,你都需要在测试中提供服务,没有必要$provider(这包括选项1,如果你只是想让你的过滤器可用,则不需要做任何事情):

beforeEach(module('ngSanitize'));    

beforeEach(inject(function(_ngSanitize_) { // the underscores are needed
    mockNgSanitize = _ngSanitize_;
}));
Run Code Online (Sandbox Code Playgroud)

此外,确保所有js文件都被业力拾取并加载.您可以karma.conf.js通过将它们添加到files:属性来定义它.

2.在服务上存根方法

我喜欢存根,在编写测试时发现它们非常有用.你的测试应该只测试一件事,在你的情况下是一个过滤器.存根使您可以更好地控制测试,并允许您隔离测试中的事物.

通常过滤器,控制器,任何东西都会调用许多其他东西(服务或工厂,如$ http或ngSanitize).

假设您的过滤器正在使用ngSanitize $sanitize来清理某些html,您可以使用该方法来返回已定义的已清理的html,以测试您的期望:

// in a beforeEach

spyOn(mockNgSanitize, "$sanitize").and.returnValue('<some>sanitized<html>');

mockNgSanitized.$sanitize(yourDirtyHtml);
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅茉莉花文档.

你可能不得不玩间谍服务,但这应该可行.

3.模拟整个服务

我不认为你想要使用这个选项,因为它会让你疯狂搞清楚什么需要嘲笑加上模拟可以创造不切实际的期望,而且对你的用例并不是特别有用.如果你真的想要去,那么类似下面的东西正朝着正确的方向前进(再次参见茉莉花文档)

beforeEach(function() {
    mockNgSanitize = ('ngSanitize', ['linky', '$sanitize', '$sanitizeProvider'];
});

it('mocks the ngSanitize service', function() {
    expect(mockNgSanitize.linky).toBeDefined(); 
});
Run Code Online (Sandbox Code Playgroud)

注意:在上面的所有代码中,请确保继续在describe块的顶部声明任何变量.