如何使用带有 $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];

工作代码: http://plnkr.co/edit/xroiqBdGOv4phxtnSWbU?p=preview