【问题标题】:Dealing With Dependencies in angularjs Testing处理 angularjs 测试中的依赖关系
【发布时间】:2016-10-03 18:14:42
【问题描述】:

这是为了工作(我有权限),所以我不能发布确切的代码。

所以我必须测试一个大型模块的控制器。该模块有一个大型配置功能,其中包含用于不同页面逻辑的一堆控制器。

对于实际应用程序,它加载了 bower,这很烦人,因为我正在使用 Karma-Browserify 和 npm 进行测试。所以依赖是一团糟。我基本上必须将从 bower.json 加载的所有内容导入 package.json。

这是我的 karma.conf.js:

module.exports = function(config) {
  config.set({
    basePath: 'resources',
    browserify: {
      debug: true,
      transform: [ 'browserify-shim' ]
    },
    browsers: [ 'PhantomJS' ],
    captureTimeout: 60000,
    client: {
      mocha: {}
    },
    files: [
      'tests/assist/test.js',
      'assets/scripts/libs/logger.min.js'
    ],
    frameworks: [ 'browserify', 'phantomjs-shim', 'mocha', 'chai' ],
    port: 8080,
    preprocessors: {
      'tests/assist/controller.js': [ 'browserify' ]
    },
    reporters: [ 'mocha', 'coverage' ],
    singleRun: true
  });
};

所以下面的代码是我的 test.js(删除了一些公司特定的名称)。我还需要放 angular.mock。否则就不行了

require('angular');
require('angular-mocks');

//Main module needs these
jQuery = require('jquery');
require('angular-bootstrap');
require('angular-recaptcha');
require('angular-ui-router');
require('ngstorage');
require(**The path to the main module**);
require(**The path to a service it uses**);
require(**The path to a service it uses**);
require(**The path to a service it uses**);

describe('Blah', function () {
  beforeEach(angular.mock.module('myApp'));

  var $controller;

  beforeEach(angular.mock.inject(function(_$controller_) {
    $controller = _$controller_;
  }));

  describe('blahblah', function () {
    it('sets loading to true', function () {
      var $scope = {};
      var controller = $controller('controller', {$scope: $scope});
      assert($scope.showLoading === true);
    });
  });
});

主模块:

(function() {
    'use strict';
})();


// Jquery noconflict
jQuery.noConflict();

var myApp = angular.module('myApp', ['ui.router', 'ngStorage', 'vcRecaptcha', 'ui.bootstrap']);

myApp.config(['$stateProvider', '$urlRouterProvider', '$locationProvider', function($stateProvider, $urlRouterProvider, $locationProvider) {
    ...
}])
.run([blah bunch of dependencies]) {
   ...
}]);

控制器(单独的文件):

'use strict';

myApp.controller('controller', ['$scope', '$http', '$localStorage', 'service1', 'service2', 'service3',
    function ($scope, $http, $localStorage, service1, service2, service3) {
   ..
    }
...

如您所见,我处于依赖地狱中。我在角度站点上进行了示例测试,主要问题是依赖项和 myApp 对控制器不可见。 “ReferenceError: Can't find variable: myApp”在控制器/服务中

如果有人有更好的测试方法,我会全力以赴。

【问题讨论】:

  • 我不一定有更好的方法来测试它,就像我有一个建议一样。 Angularjs 并不是用一堆控制器来编写的,事实上,在 Angular2 中,他们完全取消了控制器,因为人们错过了使用它们。我建议回顾一下这些文件,并考虑走一条更具指导性的中心路线。我的公司最近从控制器切换到工厂和指令,并注意到了重大改进。
  • 感谢您的评论。我只是一个实习生,所以我只是应该测试一个我没有写的代码库,所以我真的不能做任何切换等。希望 estus 的回答能解决它。

标签: javascript angularjs node.js browserify karma-mocha


【解决方案1】:

这与依赖地狱无关,也与测试无关。

代码似乎依赖于myApp 全局变量,这与Angular 模块的用途完全相反。

myApp应该是在每个函数作用域中动态定义的局部变量

(function () {

var myApp = angular.module('myApp', [...]);
...

})();

(function () {

var myApp = angular.module('myApp');
myApp.controller('controller', ...)
...

})();

【讨论】:

  • 如果您有 10 个控制器并想稍微清理一下,您仍然可以将控制器放在另一个 js 文件中,这难道不是正确的吗?您只需通过角度引用您的模块,而不是像上面所说的那样通过全局变量。例如:angular.module('myApp').controller(.......)
  • 请忽略此评论
  • @Ohjay44 当然,这是一个偏好问题。它对于单个控制器定义可能是多余的,但有利于样式一致性。
  • 嘿 estus 它解决了我的“找不到 myApp”问题,谢谢!整体测试仍然无法正常工作,我认为至少还有 5 个错误要通过哈哈。现在我有:null 不是对象(正在评估 'document.getElementById("appURL").value。如果您知道如何修复它。错误在服务文件中。
  • @PatrickDD 很可能是因为该元素不在 DOM 中,而 getElementById("appURL") 返回 null。请记住,Angular 规范中的根元素与 DOM 是分离的,所有 DOM 调用都应该最好被模拟。随时发布有关每个问题的相关问题。
猜你喜欢
  • 2015-05-11
  • 2018-08-27
  • 1970-01-01
  • 1970-01-01
  • 2011-04-22
  • 2018-09-23
  • 1970-01-01
  • 1970-01-01
  • 2019-12-01
相关资源
最近更新 更多