如何使用带有 $interval.flush 和 clock.tick 的 Sinon 测试更新 $scope
How to update $scope using Sinon test with $interval.flush and clock.tick
所以,我有一个带有相关示例代码的 plunker 设置:
http://plnkr.co/edit/KcpzxTnwFNnvhYXyPq6B?p=preview
我的问题是,我在 home.controller.js
中有一个函数
PopularMovies.query(function(data) {
results = data;
findMovie(results[0]);
console.log("$interval Start", Date.now());
$interval(function() {
++idx;
console.log("$interval idx[" + idx + "]", Date.now());
console.log("results[idx % results.length]", results[idx % results.length]);
findMovie(results[idx % results.length]);
}, 5000);
});
触发后,预计它每 5000 毫秒调用一次 findMovie()
。
为了测试这个,我在 home.controller.spec.js 文件中编写了一个测试:
it('should rotate movies every 5 seconds', function() {
this.clock = sinon.useFakeTimers();
var myStub = sinon.stub(PopularMovies, 'query').callsFake(function(cb) {
cb(['tt0076759', 'tt0080684', 'tt0086190']);
});
$controller('HomeController', {
$scope: $scope,
$interval: $interval,
omdbApi: omdbApi,
PopularMovies: PopularMovies
});
$rootScope.$apply();
// should have a default movie
console.log("$scope", $scope);
console.log("$scope.result", $scope.result);
console.log("results[0].Title", results[0].Title);
expect($scope.result.Title).to.equal(results[0].Title);
// should update after 5 seconds
console.log(Date.now(), this.clock);
this.clock.tick(5000);
$interval.flush(5000);
console.log(Date.now(), this.clock);
console.log("$scope", $scope);
console.log("$scope.result", $scope.result);
console.log("results[1].Title", results[1].Title);
expect($scope.result.Title).to.equal(results[1].Title);
// should update after 5 seconds
this.clock.tick(5000);
$interval.flush(5000);
console.log("$scope", $scope);
console.log("$scope.result", $scope.result);
console.log("results[2].Title", results[2].Title);
expect($scope.result.Title).to.equal(results[2].Title);
// should return to default
this.clock.tick(5000);
$interval.flush(5000);
expect($scope.result.Title).to.equal(results[0].Title);
this.clock.restore();
});
我的期望是 this.clock.tick(5000);
and/or $interval.flush(5000);
会增加计时器,angular 会更新 $scope.result.
在第一次调用时,$scope 被更新。但是,任何后续计时器都无法更新规范文件中的 $scope。
我在使用 Jasmine 之前写过一次这些测试,我在 $scope 更新方面没有遇到任何问题。但是,我正在尝试过渡到 Sinon,所以请帮助我完成这项工作!
原来我遇到的问题是 omdb.find 服务存根以及从 Jasmine 的 Object.fn.calls.mostRecent()
转换为 Sinon 的 Object.fn.args
,它没有 mostRecent() 函数。我更改了代码以查看 args 数组中的最后一个 arg。
在home.controller.spec.js,我改了
var args = _omdbApi_.find.args[0][0];
到
var args = _omdbApi_.find.args;
args = args[args.length - 1][0];
所以,我有一个带有相关示例代码的 plunker 设置: http://plnkr.co/edit/KcpzxTnwFNnvhYXyPq6B?p=preview
我的问题是,我在 home.controller.js
中有一个函数PopularMovies.query(function(data) {
results = data;
findMovie(results[0]);
console.log("$interval Start", Date.now());
$interval(function() {
++idx;
console.log("$interval idx[" + idx + "]", Date.now());
console.log("results[idx % results.length]", results[idx % results.length]);
findMovie(results[idx % results.length]);
}, 5000);
});
触发后,预计它每 5000 毫秒调用一次 findMovie()
。
为了测试这个,我在 home.controller.spec.js 文件中编写了一个测试:
it('should rotate movies every 5 seconds', function() {
this.clock = sinon.useFakeTimers();
var myStub = sinon.stub(PopularMovies, 'query').callsFake(function(cb) {
cb(['tt0076759', 'tt0080684', 'tt0086190']);
});
$controller('HomeController', {
$scope: $scope,
$interval: $interval,
omdbApi: omdbApi,
PopularMovies: PopularMovies
});
$rootScope.$apply();
// should have a default movie
console.log("$scope", $scope);
console.log("$scope.result", $scope.result);
console.log("results[0].Title", results[0].Title);
expect($scope.result.Title).to.equal(results[0].Title);
// should update after 5 seconds
console.log(Date.now(), this.clock);
this.clock.tick(5000);
$interval.flush(5000);
console.log(Date.now(), this.clock);
console.log("$scope", $scope);
console.log("$scope.result", $scope.result);
console.log("results[1].Title", results[1].Title);
expect($scope.result.Title).to.equal(results[1].Title);
// should update after 5 seconds
this.clock.tick(5000);
$interval.flush(5000);
console.log("$scope", $scope);
console.log("$scope.result", $scope.result);
console.log("results[2].Title", results[2].Title);
expect($scope.result.Title).to.equal(results[2].Title);
// should return to default
this.clock.tick(5000);
$interval.flush(5000);
expect($scope.result.Title).to.equal(results[0].Title);
this.clock.restore();
});
我的期望是 this.clock.tick(5000);
and/or $interval.flush(5000);
会增加计时器,angular 会更新 $scope.result.
在第一次调用时,$scope 被更新。但是,任何后续计时器都无法更新规范文件中的 $scope。
我在使用 Jasmine 之前写过一次这些测试,我在 $scope 更新方面没有遇到任何问题。但是,我正在尝试过渡到 Sinon,所以请帮助我完成这项工作!
原来我遇到的问题是 omdb.find 服务存根以及从 Jasmine 的 Object.fn.calls.mostRecent()
转换为 Sinon 的 Object.fn.args
,它没有 mostRecent() 函数。我更改了代码以查看 args 数组中的最后一个 arg。
在home.controller.spec.js,我改了
var args = _omdbApi_.find.args[0][0];
到
var args = _omdbApi_.find.args;
args = args[args.length - 1][0];