测试 Angular $emit 和 $on 事件
Testing Angular $emit and $on events
我正在尝试为控制器中的事件编写单元测试。
下面是我的控制器
myApp.controller('ParentCtrl', ['$scope', function ($scope) {
$scope.message = "Some text in parent";
$scope.$on("update_parent_controller", function(event, message){
$scope.message = message;
});
}])
.controller('ChildCtrl', ['$scope', function ($scope) {
$scope.clickFunction = function() {
$scope.message = "Parent updated from child controller";
$scope.$emit('update_parent_controller', $scope.message);
}
}]);
下面是我正在尝试编写的测试
describe("Hello Controller Test", function () {
var ctrl, scope;
beforeEach(module("myApp"));
beforeEach(inject(function ($controller, $rootScope) {
scope = $rootScope.$new();
spyOn(scope, '$on');
ctrl = $controller("ParentCtrl", {
$scope : scope
});
}));
it('should change ParentCtrl message property from child ctrl', function (){
var new_hero = 'Ralf ninja turtle',
sub_scope = scope.$new();
sub_scope.$emit('update_parent_controller', new_hero);
expect(scope.$on).toHaveBeenCalled();
expect(scope.message).toBe('Ralf ninja turtle'); //Getting err here
});
});
我期待更新父控制器中的消息,
但是测试失败了 expect(scope.message).toBe('Ralf ninja turtle');
您需要在调用 $emit
之后调用 $scope.$apply()
。这会在应用程序中自动发生,但需要在测试中明确调用。
在测试用例中 scope.$on
被监视了。
spyOn(scope, '$on');
为了调用实际的功能,必须加上.and.callThrough()
。
spyOn(scope, '$on').and.callThrough();
这是一个完整的工作示例:
angular.module('myApp', []).controller('ParentCtrl', ['$scope', function ($scope) {
$scope.message = "Some text in parent";
$scope.$on("update_parent_controller", function(event, message){
$scope.message = message;
});
}]);
describe("Hello Controller Test", function () {
var ctrl, scope;
beforeEach(module("myApp"));
beforeEach(inject(function ($controller, $rootScope) {
scope = $rootScope.$new();
spyOn(scope, '$on').and.callThrough(); // <-- This is the fix
ctrl = $controller("ParentCtrl", {
$scope : scope
});
}));
it('should change ParentCtrl message property from child ctrl', function (){
var new_hero = 'Ralf ninja turtle',
sub_scope = scope.$new();
sub_scope.$emit('update_parent_controller', new_hero);
expect(scope.$on).toHaveBeenCalled();
expect(scope.message).toBe('Ralf ninja turtle'); //Getting err here
});
});
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.4/jasmine.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.4/jasmine.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.4/jasmine-html.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.4/boot.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular-mocks.js"></script>
我正在尝试为控制器中的事件编写单元测试。
下面是我的控制器
myApp.controller('ParentCtrl', ['$scope', function ($scope) {
$scope.message = "Some text in parent";
$scope.$on("update_parent_controller", function(event, message){
$scope.message = message;
});
}])
.controller('ChildCtrl', ['$scope', function ($scope) {
$scope.clickFunction = function() {
$scope.message = "Parent updated from child controller";
$scope.$emit('update_parent_controller', $scope.message);
}
}]);
下面是我正在尝试编写的测试
describe("Hello Controller Test", function () {
var ctrl, scope;
beforeEach(module("myApp"));
beforeEach(inject(function ($controller, $rootScope) {
scope = $rootScope.$new();
spyOn(scope, '$on');
ctrl = $controller("ParentCtrl", {
$scope : scope
});
}));
it('should change ParentCtrl message property from child ctrl', function (){
var new_hero = 'Ralf ninja turtle',
sub_scope = scope.$new();
sub_scope.$emit('update_parent_controller', new_hero);
expect(scope.$on).toHaveBeenCalled();
expect(scope.message).toBe('Ralf ninja turtle'); //Getting err here
});
});
我期待更新父控制器中的消息, 但是测试失败了 expect(scope.message).toBe('Ralf ninja turtle');
您需要在调用 $emit
之后调用 $scope.$apply()
。这会在应用程序中自动发生,但需要在测试中明确调用。
在测试用例中 scope.$on
被监视了。
spyOn(scope, '$on');
为了调用实际的功能,必须加上.and.callThrough()
。
spyOn(scope, '$on').and.callThrough();
这是一个完整的工作示例:
angular.module('myApp', []).controller('ParentCtrl', ['$scope', function ($scope) {
$scope.message = "Some text in parent";
$scope.$on("update_parent_controller", function(event, message){
$scope.message = message;
});
}]);
describe("Hello Controller Test", function () {
var ctrl, scope;
beforeEach(module("myApp"));
beforeEach(inject(function ($controller, $rootScope) {
scope = $rootScope.$new();
spyOn(scope, '$on').and.callThrough(); // <-- This is the fix
ctrl = $controller("ParentCtrl", {
$scope : scope
});
}));
it('should change ParentCtrl message property from child ctrl', function (){
var new_hero = 'Ralf ninja turtle',
sub_scope = scope.$new();
sub_scope.$emit('update_parent_controller', new_hero);
expect(scope.$on).toHaveBeenCalled();
expect(scope.message).toBe('Ralf ninja turtle'); //Getting err here
});
});
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.4/jasmine.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.4/jasmine.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.4/jasmine-html.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.4/boot.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular-mocks.js"></script>