AngularJS (1.5) 中的单元测试控制器,当这些控制器作为模块导出时(头痛...)
Unit testing controllers in AngularJS (1.5), when those controllers are exported as modules (headache...)
所以,我正在尝试 运行 在 Angular 1.5 应用程序中的控制器上进行单元测试,以便从现在开始我可以为所有其他控制器进行 TDD。但是,它变得有点头疼。
所有讨论测试 ng-controller 的教程和博客文章似乎都是通过注入他们的应用程序使用的控制器,并注入他们的实际应用程序来实现的。
我正在构建的应用程序为其控制器导出了一个函数,我想知道这是否是导致我头疼的原因。
这是一个例子:
// 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 中的单元测试不是很熟悉,我只是在努力加入这些点。有没有人有任何明智的建议?
好的,现在整理一下。我最终修改了我的控制器文件,使其看起来像这样:
// 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...
})
现在我所有的测试都可以访问控制器。希望这对将来的某人有用。 :)
所以,我正在尝试 运行 在 Angular 1.5 应用程序中的控制器上进行单元测试,以便从现在开始我可以为所有其他控制器进行 TDD。但是,它变得有点头疼。
所有讨论测试 ng-controller 的教程和博客文章似乎都是通过注入他们的应用程序使用的控制器,并注入他们的实际应用程序来实现的。
我正在构建的应用程序为其控制器导出了一个函数,我想知道这是否是导致我头疼的原因。
这是一个例子:
// 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 中的单元测试不是很熟悉,我只是在努力加入这些点。有没有人有任何明智的建议?
好的,现在整理一下。我最终修改了我的控制器文件,使其看起来像这样:
// 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...
})
现在我所有的测试都可以访问控制器。希望这对将来的某人有用。 :)