真正嘲讽的供应商 [英] Truly mocking providers

查看:177
本文介绍了真正嘲讽的供应商的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以基本上有关于如何忽略对模块的config /运行/提供商块,而不做一些文件加载​​顺序为黑客单元测试的信息。假设如下:

So basically there's no information on how to omit config/run/provider blocks on modules without doing some file load ordering hack for unit-tests. Assume the following:

// dependency chain for providers:
// aaa <- bbb <- ccc


angular.module('module0').provider('bbb', [
  'aaaProvider', 
  function (aaaProvider) {
    // aaaProvider definition
    ...
  });

angular.module('module1').provider('ccc', [
  'bbbProvider',
  function (bbbProvider) {
    // bbbProvider definition
    ...
  });

angular.module('module1').controller('controller', [
  function () {
    // controller definition
  }]);

现在假设我们正在编写一个单元测试控制器。我们将如何做呢?

Now assume that we are writing a unit test for controller. How would we do that?

module('module1');
inject(function ($controller, $rootScope) {
  ...
});

哎呀,我们有一个问题。 模块(模块1')将触发提供商定义 CCC ,即对 BBB依赖,即对 AAA 依赖。所以,除非我们为prevent提供商定义 CCC 被触发模块1 ,我们将在运行code,它无关与控制器我们的单元测试。

Oops, we have a problem. module('module1') will trigger provider definition for ccc, that has dependency on bbb, that has dependency on aaa. So unless we prevent provider definition for ccc being triggered on module1, we will running code that has nothing to do with the controller we are unit testing.

我们可以模拟 BBB 使用模块(函数($提供){...}); 符号而这样,我们就不需要加载模块0 的。

We can mock bbb by using module(function ($provide) { ... }); notation and that way we won't need to load module0 at all.

但是,这并没有解决它 CCC 。有没有办法让我停止运行了。

But that doesn't solve it for ccc. There's no way for me to stop it from running.

问:有没有办法从运行 CCC定义模块1 >供应商,其中有无关控制器我们是单元测试?

Question: Is there a way to stop module1 from running the definition of ccc provider, which has nothing to do with controller we are unit testing?

事情到目前为止,我已经试过:

Things I've tried so far:


  • 在单元测试覆盖的定义:

  • Override definition in unit test:

angular.module('模块1')提供商('CCC',[功能(){}]);

推荐答案

首先,你需要在你的app.js创建两个模块

First you need to create in your app.js two modules

module1internal - 这个模块将不会有依赖性和将被用于所有
您的应用程序提供商

module1internal - this module will not have dependencies and will be used for all your application providers

angular.module('module1internal', []);

模块1 - 这个模块依赖于module1internal,将包括所有其他的依赖,配置和运行块

module1 - this module depends on the module1internal and will include all other dependencies, config and run block

angular.module('module1', ['module1internal','bbbProvider']);

在您的应用程序,你应该只使用内部模块,例如,而不是

in your app you should use only the internal module for example instead of

angular.module('module1').controller('controller', [
  function () {
    // controller definition
  }]);

你应该使用

angular.module('module1internal').controller('controller', [
      function () {
        // controller definition
      }]);

该测试将是这样的:

The tests will look like this:

'use strict';

describe('Controller: TheController', function () {

  // mock second level dependencies
  beforeEach(function () {
    module('module1internal');
    module({
      bbb: {}
    });
  });

  var TheController, scope,
    cccMock;

  // mock injected providers
  beforeEach(inject(function (_ccc_) {
    cccMock = mock(_ccc_);
  }));


  // Initialise the controller and mock scope 
  beforeEach(inject(function ($controller, $rootScope) {
    scope = $rootScope.$new();
    TheController = $controller('TheController', {
      $scope: scope
    });

  }));

  it(' should call ccc functionA on functionThatUsesFunctionA call', function () {
    TheController.functionThatUsesFunctionA("someValue");
    expect(cccMock.functionA).toHaveBeenCalledWith("someValue");
  });



  //create spy on all provider's methods(mock it)
  function mock(angularServiceToMock) {

    for (var i = 0; i < Object.getOwnPropertyNames(angularServiceToMock).length; i++) {
      spyOn(angularServiceToMock, Object.getOwnPropertyNames(angularServiceToMock)[i]);
    }
    return angularServiceToMock;
  }

});

这篇关于真正嘲讽的供应商的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆