如何模拟角度测试模块

时间:2014-02-12 17:46:01

标签: javascript angularjs

假设我有一个定义为

的角度模块
var app = angular.module('app',[dependenceny1Module,dependenceny2Module,dependenceny3Module......])

其中app是一个依赖于大量其他模块的模块。 现在进行单元测试,我可以使用

模拟模块
mock('app') 

但我必须为所有依赖模块创建模拟模块,如下所示

mockDependency1 = angular.module('dependency1Module')
mockDependency1 = angular.module('dependency2Module')

或者我必须加载包含这些模块的所有脚本文件。

我想知道在这里嘲笑依赖模块的最佳方法是什么?特别是当依赖模块太多时。

3 个答案:

答案 0 :(得分:8)

查看requireJs以加载您的依赖项。使用RequireJs,您可以为生产代码和测试代码加载不同的文件。

这是一个(基本)例子。

假设您有一个javascript文件,用于定义角度模块(名为app.js):

define(['dependency1Module', 'dependency2Module'], function(dependency1Module, dependency2Module) {
   var app = angular.module('app',['dependenceny1Module', 'dependenceny2Module']);
   return app;
}

模块dependency1Module,dependency2Module,...有类似的设置:

define(function() {
   var module = angular.module('dependenceny1Module');
   return module;
}

现在你需要一个引导程序文件(名为bootstrap.js来定义文件的位置。所以你将有两个引导程序文件:一个是你的生产代码(使用某些库的可能的缩小版本)和一个用于测试目的的版本:

require.config({
  baseUrl: "path/to/production|test scripts",
  paths: {
    angular: 'path/to/angular',
    jquery: 'path/to/jquery',
  },
  shim: {
    angular: {
      exports: 'angular',
      deps: ['jquery']
    }
  }
});

require(["angular", "app", ], function(angular, app) {
  angular.element(document).ready(function() {
    angular.bootstrap(document, ['app']);
  });
});

您可以为要模拟的模块定义不同的路径,而不是更改baseUrl

paths: {
   dependency1Module: 'path/to.mock/dependency1Module'
}

最后一步是在你的html代码(生产或测试)中插入bootstrap文件:

<script type="text/javascript" src="path/to/require.js"></script>
<script type="text/javascript" src="path/to/bootstrap(production|test).js"></script>

这是一个基本的requirejs设置。当然,在你可以使用某种角度类型(例如控制器,服务......)之前,你还需要为它设置一个requirejs模块(例如require app.js )。

答案 1 :(得分:1)

模仿自己的应用程序会有所帮助。

如果您的应用看起来像这样:

var app = angular.module('app',[dependenceny1Module, dependenceny2Module, dependenceny3Module......])

并包含50个过滤器,指令和控制器等内容。其中一些依赖依赖尼特模块,其中一些依赖依赖尼姆模块。

根据他们的责任和依赖性将他们分开。

var mymodule1 = angular.module('mymodule1',[dependenceny2Module, dependenceny3Module])

var mymodule2 = angular.module('mymodule2',[dependenceny1Module,])

然后让你的应用依赖于你自己的模块:

var app = angular.module('app',[ mymodule1, mymodule2])

您的app应该包含大部分引导代码。

现在,当您要测试controller13 mymodule2时,您只需要模拟mymodule2的依赖项,如果该模块具有依赖项。因此测试套件不会加载app他们只会加载他们测试的模块。

this example MyMainCtrl1的{​​{1}}测试仅关注来自mymodule1的{​​{1}},即使整个s1取决于external1appexternal1external2

答案 2 :(得分:0)

这一切都取决于你真正想要测试的内容,如果你是单元测试,你想尽可能少地加载/模拟。例如,如果您对控制器进行单元测试,则模拟模块并仅加载/模拟它使用的任何依赖项。