【问题标题】:Reusing angular mocks in Jasmine tests using $provide使用 $provide 在 Jasmine 测试中重用 Angular 模拟
【发布时间】:2015-05-15 07:58:54
【问题描述】:

我希望重用我的模拟,而不是在每个将它们作为依赖项的单元测试中设置它们。但我很难弄清楚如何正确注入它们。

这是我对单元测试设置的尝试,当然失败了,因为 ConfigServiceMockProvider 不存在。

describe('LoginService tests', function () {

  var LoginService;

  beforeEach(module('mocks'));

  beforeEach(module('services.loginService', function ($provide, _ConfigServiceMock_) {
    $provide.value("ConfigService", _ConfigServiceMock_);

    /* instead of having to type e.g. everywhere ConfigService is used
    *  $provide.value("ConfigService", { 'foobar': function(){} });
    */
  });

  beforeEach(inject(function (_LoginService_) {
    LoginService = _LoginService_;
  });
}

配置服务模拟

angular.module('mocks').service('ConfigServiceMock', function() {
  this.init = function(){};
  this.getValue = function(){};
}

我意识到我可能可以让 ConfigServiceMock.js 创建一个全局窗口对象,因此不需要像这样加载它。但我觉得应该有更好的方法。

【问题讨论】:

  • mocks.ConfigServiceMock的定义在哪里
  • 添加到问题中
  • 模块名称是mock 而不是mocks.ConfigServiceMock。能不能换成beforeEach(module('mocks'));试试看。
  • 你说得对,我写信给 SO 时拼错了。让我试着说明一下,问题不在于编译,而是我正在寻找一种模式来将预定义的模拟注入到我的单元测试中。
  • 你的意思是说_ConfigServiceMock_服务注入不起作用?

标签: angularjs testing mocking jasmine karma-runner


【解决方案1】:

试试这样的:

describe('Using externally defined mock', function() {
  var ConfigServiceMock;

  beforeEach(module('mocks'));

  beforeEach(module('services.configService', function($provide) {
    $provide.factory('ConfigService', function() {return ConfigServiceMock;});
  }));

  beforeEach(module('services.loginService'));

  beforeEach(inject(function (_ConfigServiceMock_) {
    ConfigServiceMock = _ConfigServiceMock_;
  }));

  // Do not combine this call with the one above
  beforeEach(inject(function (_LoginService_) {
    LoginService = _LoginService_;
  }));

  it('should have been given the mock', function() {
    expect(ConfigServiceMock).toBeDefined('The mock should have been defined');
    expect(LoginService.injectedService).toBeDefined('Something should have been injected');
    expect(LoginService.injectedService).toBe(ConfigServiceMock, 'The thing injected should be the mock');
  });
});

根据this answer,您必须先将所有电话拨给module,然后再拨给inject

这引入了一点 catch-22,因为您必须在规范中引用您的 ConfigServiceMock(通过 inject),然后才能在 LoginService 上设置它(在 module 调用中完成)

解决方法是将角度工厂函数设置为 ConfigService 依赖项。这将导致 Angular 延迟加载服务,到那时您将收到对 ConfigServiceMock 的引用。

【讨论】:

  • 太棒了!不敢相信没有这方面的文档,因为模拟的可重用性在任何大型应用程序中都很重要。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-07
  • 1970-01-01
相关资源
最近更新 更多