28

基本上,我对 Mocha 非常有经验(编写了数千个单元测试),而且我对 AngularJS 很陌生(仅编写了我的第一个项目)。

现在我想知道如何使用 Mocha 对所有 AngularJS 的东西进行单元测试。

我知道 Mocha 在浏览器中运行,我已经这样做了。但是我如何构建和设置东西呢?

我想我需要:

  • 加载 AngularJS
  • 加载摩卡
  • 加载我的测试

在每个测试中,我需要加载一个控制器、一个服务……来进行测试。我怎么做?我没有使用 require.js 或类似的东西,这些文件只是脚本文件,基本上具有以下内容:

angular.controller('fooController', [ '$scope', function ($scope) {
  // ...
}]);

如何在测试中引用和实例化该控制器?这同样适用于服务,指令,......

我需要为$scope, $http& co 创建模拟吗?为我自己,或者有什么帮助?

请注意,我知道有 Karma 测试运行器(以前称为 Testacular),但我不想完全切换我的测试运行器。

4

2 回答 2

14

一种方法是Angular $injector在您的测试中使用:

myModule_test.js

suite('myModule', function(){
  setup(function(){
    var app = angular.module('myModule', []);
    var injector = angular.injector(['myModule', 'ng']);
    var service = injector.get('myService');
  });

  suite('myService', function(){
    test('should return correct value', function(){
       // perform test with an instance of service here
    });
  });
});

html应该看起来像这样:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>myModule tests</title>
  <link rel="stylesheet" media="all" href="vendor/mocha.css">
</head>
<body>
  <div id="mocha"><p><a href=".">Index</a></p></div>
  <div id="messages"></div>
  <div id="fixtures"></div>
  <script src="vendor/mocha.js"></script>
  <script src="vendor/chai.js"></script>
  <script src="angular.min.js"></script>
  <script src="myModule.js"></script>
  <script>mocha.setup('tdd')</script>
  <script src="myModule_test.js"></script>
  <script>mocha.run();</script>
</body>
</html>
于 2013-11-21T22:07:16.230 回答
3

如果您正在创建一个没有任何依赖关系且不一定特定于角度的角度服务,您可以以与角度无关的方式编写模块,然后为它编写一个单独的小型角度包装器,或测试存在角度,并有条件地为它创建服务。

这是我用来创建可用于 Angular、浏览器和节点模块(包括 mocha 测试)的模块的方法示例:

(function(global) {
    //define your reusable component
    var Cheeseburger = {};

    if (typeof angular != 'undefined') {
        angular.module('Cheeseburger', [])
            .value('Cheeseburger', Cheeseburger);
    }
    //node module
    else if (typeof module != 'undefined' && module.exports) {
        module.exports = Cheeseburger
    }
    //perhaps you'd like to use this with a namespace in the browser
    else if (global.YourAppNamespace) {
        global.YourAppNamespace.Cheeseburger = Cheeseburger
    }
    //or maybe you just want it to be global
    else {
        global.Cheeseburger = Cheeseburger
    }
})(this);
于 2014-09-09T19:28:39.097 回答