AngularJS(1.5)中的单元测试控制器,当这些控制器作为模块导出时(头痛......)

时间:2016-07-13 15:25:18

标签: angularjs unit-testing karma-mocha

所以,我试图在Angular 1.5应用程序中的Controller上运行单元测试,这样我就可以从现在开始为每个其他控制器执行TDD。但是,它变得有点头疼。

所有关于测试控制器的教程和博客文章都是通过注入他们的应用程序使用的控制器并注入他们的实际应用程序来实现的。

我正在构建的应用程序为其控制器导出一个函数,我想知道这是否是导致我头痛的原因。

以下是一个例子:

// Controller file
const myController = (app) => {
  const controller = app.controller('MyCtrl', ['$scope', 'SomeService', ($scope, SomeService) => {
    // Stuff in here
}])

  return controller
}

module.exports = {
  init: myController
}

上述内容将通过以下方式调用:

myController.init(angular.module('myApp'))

所以,在我对这个控制器的单元测试中,我试图以这种方式进行设置:

// Test file
const myController = require('../path/to/myController')
const app = angular.module('testModule', [])
myController.init(app)

describe('Controller tests: ', () => {
  it('should work', inject(($controller) => {
    const testMyCtrl = $controller('MyCtrl', {
      $scope: {}
    })
    assert.equal(true, true)
  }
}

但是,当我尝试测试它时(使用Karma和Mocha),我得到:

Argument 'MyCtrl' is not a function, got undefined

可悲的是,我并不熟悉AngularJS中的单元测试,我只是在努力加入这里的点。有没有人有任何圣人建议?

1 个答案:

答案 0 :(得分:0)

好的,现在整理一下。我最终修改了我的控制器文件,所以它看起来像这样:

// Controller file
const MyCtrl = ($scope, SomeService) => {
  // Stuff here
}

module.exports = myCtrl

然后我在我的app.js文件中实例化它:

import MyCtrl from './path/to/controller'
MyCtrl.$inject = ['$scope', SomeService] // Where 'SomeService' is also imported into this file
const app = angular.module('MyApp', [])
app.controller('MyCtrl', MyCtrl)

然后在我的单元测试中,我有一个' test-app.js'创建测试应用程序的文件,并以相同的方式实例化它所需的服务和控制器(实际上这可能是不必要的,使用真正的应用程序也可以正常工作,但将它们完全分开会感觉更好)。然后在测试我的控制器的文件中,我有;

// Controller's unit test file
describe('MyCtrl tests: ', () => {
  var myCtrl
  var $scope
  var SomeService

  beforeEach(angular.mock.module('testApp')) // testApp is created in test-app.js
  beforeEach(angular.mock.inject(($controller, $rootScope, _SomeService_) => {
    SomeService = _SomeService_
    $scope = $rootScope.$new()
    MyCtrl = $controller('MyCtrl', {
      $scope: $scope,
      SomeService: SomeService
    }
  }

  // tests...
})

现在我的所有测试都可以访问控制器。希望这对未来的某些人有用。 :)