间谍不与 Angular、Jasmine 和 Sinon 合作
Spying not working with Angular, Jasmine and Sinon
我试图监视控制器中定义的方法,但无论我做什么,我都会看到测试失败并显示以下消息:
Error: Expected a spy, but got Function.
我将 Karma、Jasmine 和 Sinon 与 Angular 一起使用。我很确定一切都设置正确,因为只从 $scope 中读取属性的测试通过了。
例如,我有这个非常简单的应用程序模块:
angular.module('app', []);
还有这个非常简单的控制器:
angular.module('app').controller('myController', ['$scope', function($scope) {
$scope.test = '';
$scope.setTest = function (newString) {
$scope.test = newString || 'default';
}
$scope.updateTest = function (newString) {
$scope.setTest(newString);
};
}]);
我的规格文件如下:
describe('myController', function () {
'use strict';
beforeEach(module('app'));
var $scope, sandbox;
beforeEach(inject(function ($controller) {
$scope = {};
$controller('myController', { $scope: $scope });
sandbox = sinon.sandbox.create();
}));
afterEach(function () {
sandbox.restore();
});
describe('#updateTest()', function () {
beforeEach(function () {
sandbox.spy($scope, 'setTest');
});
it('updates the test property with a default value', function () {
$scope.updateTest();
expect($scope.test).toEqual('default');
});
it('calls the setTest method', function () {
$scope.updateTest();
expect($scope.setTest).toHaveBeenCalled();
});
});
});
第一个测试(它只是检查测试 属性 是否更新)通过。
我只想监视 setTest()
方法的第二个测试失败并显示上述错误消息。
如果我在 beforeEach
中注销 $scope
,我可以看到 setTest
方法并且没有脚本错误。
我错过了什么?
我猜这是因为你混合了 Jasmine 和 Sinon,我认为 Sinon 间谍 sandbox.spy()
不会与 Jasmine 匹配器 expect().toHaveBeenCalled()
一起工作。您应该选择使用哪一个:
使用 Sinon 间谍并将结果转换为原语以将其传递给 Jasmine:
sandbox.spy($scope, 'setTest');
expect($scope.setTest.called).toBeTruthy();
但是这种方法会给你更少冗长的输出:Expected true to be false
,而不是通常的 Expected spy to have been called
.
使用 Jasmine 间谍:
spyOn($scope, 'setTest');
expect($scope.setTest).toHaveBeenCalled();
您还可以查看工具 jasmine-sinon,它添加了额外的 Jasmine 匹配器并允许将 Sinon 间谍与 Jasmine 间谍匹配器一起使用。因此,您应该能够在示例中使用 like:
sandbox.spy($scope, 'setTest');
expect($scope.setTest).toHaveBeenCalled();
我试图监视控制器中定义的方法,但无论我做什么,我都会看到测试失败并显示以下消息:
Error: Expected a spy, but got Function.
我将 Karma、Jasmine 和 Sinon 与 Angular 一起使用。我很确定一切都设置正确,因为只从 $scope 中读取属性的测试通过了。
例如,我有这个非常简单的应用程序模块:
angular.module('app', []);
还有这个非常简单的控制器:
angular.module('app').controller('myController', ['$scope', function($scope) {
$scope.test = '';
$scope.setTest = function (newString) {
$scope.test = newString || 'default';
}
$scope.updateTest = function (newString) {
$scope.setTest(newString);
};
}]);
我的规格文件如下:
describe('myController', function () {
'use strict';
beforeEach(module('app'));
var $scope, sandbox;
beforeEach(inject(function ($controller) {
$scope = {};
$controller('myController', { $scope: $scope });
sandbox = sinon.sandbox.create();
}));
afterEach(function () {
sandbox.restore();
});
describe('#updateTest()', function () {
beforeEach(function () {
sandbox.spy($scope, 'setTest');
});
it('updates the test property with a default value', function () {
$scope.updateTest();
expect($scope.test).toEqual('default');
});
it('calls the setTest method', function () {
$scope.updateTest();
expect($scope.setTest).toHaveBeenCalled();
});
});
});
第一个测试(它只是检查测试 属性 是否更新)通过。
我只想监视 setTest()
方法的第二个测试失败并显示上述错误消息。
如果我在 beforeEach
中注销 $scope
,我可以看到 setTest
方法并且没有脚本错误。
我错过了什么?
我猜这是因为你混合了 Jasmine 和 Sinon,我认为 Sinon 间谍 sandbox.spy()
不会与 Jasmine 匹配器 expect().toHaveBeenCalled()
一起工作。您应该选择使用哪一个:
使用 Sinon 间谍并将结果转换为原语以将其传递给 Jasmine:
sandbox.spy($scope, 'setTest'); expect($scope.setTest.called).toBeTruthy();
但是这种方法会给你更少冗长的输出:
Expected true to be false
,而不是通常的Expected spy to have been called
.使用 Jasmine 间谍:
spyOn($scope, 'setTest'); expect($scope.setTest).toHaveBeenCalled();
您还可以查看工具 jasmine-sinon,它添加了额外的 Jasmine 匹配器并允许将 Sinon 间谍与 Jasmine 间谍匹配器一起使用。因此,您应该能够在示例中使用 like:
sandbox.spy($scope, 'setTest');
expect($scope.setTest).toHaveBeenCalled();