AngularJs 单元测试失败,因为 Karma 无法识别控制器中的 $scope.$on 侦听器
AngularJs unit test fails because Karma doesn't recognize $scope.$on listeners in the controller
事情是这样的。我一直在调查许多线程,但找不到与我的错误相关的任何内容。我正在尝试测试我的 angular 应用程序,(我想先澄清一下,我是 unitTesting 的新手)
根据 this tutorial 的说法,我已经设置好所有内容并且基本测试工作正常。但是当我包含 NgMock 模块时,我的真实 angular 应用程序并编写了一个简单的测试来测试我的一个控制器上的方法,我得到以下 stackTrace。
grunt karma:dev
Running "karma:dev" (karma) task
25 03 2016 20:41:24.754:INFO [karma]: Karma v0.13.22 server started at http://localhost:9876/
25 03 2016 20:41:24.763:INFO [launcher]: Starting browser Chrome
25 03 2016 20:41:24.771:INFO [launcher]: Starting browser Firefox
25 03 2016 20:41:28.747:INFO [Chrome 49.0.2623 (Windows 10 0.0.0)]: Connected on socket /#yRHoLsbEaJWHNtSDAAAA with id 47988329
Chrome 49.0.2623 (Windows 10 0.0.0) Unit tests del CRM: Create new message Should create a text message with the correct structure FAILED
TypeError: $scope.$on is not a function
at new <anonymous> (C:/Users/Pablo/Data/software/workspace/intellij/leadaki-core/public/dashboard/v4/js/controllers/view-conversations.js:248:12)
at e (C:/Users/Pablo/Data/software/workspace/intellij/leadaki-core/public/dashboard/v4/js/angular.min.js:39:156)
at Object.instantiate (C:/Users/Pablo/Data/software/workspace/intellij/leadaki-core/public/dashboard/v4/js/angular.min.js:39:273)
at C:/Users/Pablo/Data/software/workspace/intellij/leadaki-core/public/dashboard/v4/js/angular.min.js:80:228
at C:/Users/Pablo/Data/software/workspace/intellij/leadaki-core/public/dashboard/v4/js/angular-mocks.js:1848:12
at Context.<anonymous> (C:/Users/Pablo/Data/software/workspace/intellij/leadaki-core/test/frontend/leadaki-app-tests.js:44:30)
Chrome 49.0.2623 (Windows 10 0.0.0): Executed 1 of 1 (1 FAILED) ERROR (0.087 secs / 0.024 secs)
Firefox 45.0.0 (Windows 10 0.0.0) Unit tests del CRM: Create new message Should create a text message with the correct structure FAILED
$scope.$on is not a function
@C:/Users/Pablo/Data/software/workspace/intellij/leadaki-core/public/dashboard/v4/js/controllers/view-conversations.js:248:5
e@C:/Users/Pablo/Data/software/workspace/intellij/leadaki-core/public/dashboard/v4/js/angular.min.js:39:154
h/<.instantiate@C:/Users/Pablo/Data/software/workspace/intellij/leadaki-core/public/dashboard/v4/js/angular.min.js:39:273
Xe/this.$get</<@C:/Users/Pablo/Data/software/workspace/intellij/leadaki-core/public/dashboard/v4/js/angular.min.js:80:226
angular.mock.$ControllerDecorator</<@C:/Users/Pablo/Data/software/workspace/intellij/leadaki-core/public/dashboard/v4/js/angular-mocks.js:1848:12
@C:/Users/Pablo/Data/software/workspace/intellij/leadaki-core/test/frontend/leadaki-app-tests.js:44:30
Chrome 49.0.2623 (Windows 10 0.0.0): Executed 1 of 1 (1 FAILED) ERROR (0.087 secs / 0.024 secs)
Firefox 45.0.0 (Windows 10 0.0.0): Executed 1 of 1 (1 FAILED) ERROR (0.053 secs / 0.011 secs)
Warning: Task "karma:dev" failed. Use --force to continue.
Aborted due to warnings.
ngMock 生成的 "mock" 范围似乎不接受监听器或类似的东西。
有没有人暗示这里可能是错误的?
我可以粘贴我所有的配置文件,但我认为这些信息太多,我不想淹没 post。让我知道是否需要任何其他信息,我会添加。
在此先致谢!
describe('Unit tests del CRM: ', function () {
before(function() {
if (window.__html__) {
document.body.innerHTML = window.__html__['test/index.html'];
}
});
beforeEach(angular.mock.module('appCliengo'));
var $controller;
var $rootScope;
beforeEach(angular.mock.inject(function(_$rootScope_, _$controller_){
$rootScope = _$rootScope_;
$controller = _$controller_;
}));
describe('Create new message', function () {
it('Should create a text message with the correct structure', function () {
var $scope = {};
var controller = $controller('Contacts.viewConversation', { $scope: $scope });
var messageBody = 'Hola, me gustaria comprar un auto';
var newTextMessage = $scope.createMessage('text/plain', '123456789', 'user', 'abcdefghijk', messageBody);
expect(newTextMessage.body).to.equal(messageBody);
});
});
});
如果不查看您的确切设置很难说,但是您是否创建了一个作用域对象以注入到您的控制器中?
很多时候,您只需使用 $rootScope 对象就可以伪造它:
beforeEach(angular.mock.inject($injector => {
$controller = $injector.get('$controller');
rootScope = $injector.get('$rootScope');
}));
... test code ...
let controller = $controller('UserController', {$scope: rootScope});
... do stuff with controller ...
但是,您也可以使用 rootScope 创建一个新范围并将其输入。
事情是这样的。我一直在调查许多线程,但找不到与我的错误相关的任何内容。我正在尝试测试我的 angular 应用程序,(我想先澄清一下,我是 unitTesting 的新手)
根据 this tutorial 的说法,我已经设置好所有内容并且基本测试工作正常。但是当我包含 NgMock 模块时,我的真实 angular 应用程序并编写了一个简单的测试来测试我的一个控制器上的方法,我得到以下 stackTrace。
grunt karma:dev
Running "karma:dev" (karma) task
25 03 2016 20:41:24.754:INFO [karma]: Karma v0.13.22 server started at http://localhost:9876/
25 03 2016 20:41:24.763:INFO [launcher]: Starting browser Chrome
25 03 2016 20:41:24.771:INFO [launcher]: Starting browser Firefox
25 03 2016 20:41:28.747:INFO [Chrome 49.0.2623 (Windows 10 0.0.0)]: Connected on socket /#yRHoLsbEaJWHNtSDAAAA with id 47988329
Chrome 49.0.2623 (Windows 10 0.0.0) Unit tests del CRM: Create new message Should create a text message with the correct structure FAILED
TypeError: $scope.$on is not a function
at new <anonymous> (C:/Users/Pablo/Data/software/workspace/intellij/leadaki-core/public/dashboard/v4/js/controllers/view-conversations.js:248:12)
at e (C:/Users/Pablo/Data/software/workspace/intellij/leadaki-core/public/dashboard/v4/js/angular.min.js:39:156)
at Object.instantiate (C:/Users/Pablo/Data/software/workspace/intellij/leadaki-core/public/dashboard/v4/js/angular.min.js:39:273)
at C:/Users/Pablo/Data/software/workspace/intellij/leadaki-core/public/dashboard/v4/js/angular.min.js:80:228
at C:/Users/Pablo/Data/software/workspace/intellij/leadaki-core/public/dashboard/v4/js/angular-mocks.js:1848:12
at Context.<anonymous> (C:/Users/Pablo/Data/software/workspace/intellij/leadaki-core/test/frontend/leadaki-app-tests.js:44:30)
Chrome 49.0.2623 (Windows 10 0.0.0): Executed 1 of 1 (1 FAILED) ERROR (0.087 secs / 0.024 secs)
Firefox 45.0.0 (Windows 10 0.0.0) Unit tests del CRM: Create new message Should create a text message with the correct structure FAILED
$scope.$on is not a function
@C:/Users/Pablo/Data/software/workspace/intellij/leadaki-core/public/dashboard/v4/js/controllers/view-conversations.js:248:5
e@C:/Users/Pablo/Data/software/workspace/intellij/leadaki-core/public/dashboard/v4/js/angular.min.js:39:154
h/<.instantiate@C:/Users/Pablo/Data/software/workspace/intellij/leadaki-core/public/dashboard/v4/js/angular.min.js:39:273
Xe/this.$get</<@C:/Users/Pablo/Data/software/workspace/intellij/leadaki-core/public/dashboard/v4/js/angular.min.js:80:226
angular.mock.$ControllerDecorator</<@C:/Users/Pablo/Data/software/workspace/intellij/leadaki-core/public/dashboard/v4/js/angular-mocks.js:1848:12
@C:/Users/Pablo/Data/software/workspace/intellij/leadaki-core/test/frontend/leadaki-app-tests.js:44:30
Chrome 49.0.2623 (Windows 10 0.0.0): Executed 1 of 1 (1 FAILED) ERROR (0.087 secs / 0.024 secs)
Firefox 45.0.0 (Windows 10 0.0.0): Executed 1 of 1 (1 FAILED) ERROR (0.053 secs / 0.011 secs)
Warning: Task "karma:dev" failed. Use --force to continue.
Aborted due to warnings.
ngMock 生成的 "mock" 范围似乎不接受监听器或类似的东西。
有没有人暗示这里可能是错误的?
我可以粘贴我所有的配置文件,但我认为这些信息太多,我不想淹没 post。让我知道是否需要任何其他信息,我会添加。
在此先致谢!
describe('Unit tests del CRM: ', function () {
before(function() {
if (window.__html__) {
document.body.innerHTML = window.__html__['test/index.html'];
}
});
beforeEach(angular.mock.module('appCliengo'));
var $controller;
var $rootScope;
beforeEach(angular.mock.inject(function(_$rootScope_, _$controller_){
$rootScope = _$rootScope_;
$controller = _$controller_;
}));
describe('Create new message', function () {
it('Should create a text message with the correct structure', function () {
var $scope = {};
var controller = $controller('Contacts.viewConversation', { $scope: $scope });
var messageBody = 'Hola, me gustaria comprar un auto';
var newTextMessage = $scope.createMessage('text/plain', '123456789', 'user', 'abcdefghijk', messageBody);
expect(newTextMessage.body).to.equal(messageBody);
});
});
});
如果不查看您的确切设置很难说,但是您是否创建了一个作用域对象以注入到您的控制器中?
很多时候,您只需使用 $rootScope 对象就可以伪造它:
beforeEach(angular.mock.inject($injector => {
$controller = $injector.get('$controller');
rootScope = $injector.get('$rootScope');
}));
... test code ...
let controller = $controller('UserController', {$scope: rootScope});
... do stuff with controller ...
但是,您也可以使用 rootScope 创建一个新范围并将其输入。