在控制器中测试承诺

问题描述 投票:2回答:3

AngularJS 1.4.8

加载视图时,我在控制器中执行了以下方法。 Watcher是注入控制器的工厂。方法.list()returns蓝鸟承诺。

Watcher.list()
  .then((response) => {
    $scope.watchers = response;
  })
  .catch(notify.error);

我想像这样测试$scope.watchers

it('watchers have been loaded', function () {
  expect($scope.watchers.length).to.equal(2);
});

但收到以下错误:

Chrome 59.0.3071 (Linux 0.0.0) theApp watchersController watchers have been loaded FAILED
        Error: expected 0 to equal 2

目前,sinon stub试图模仿Wacther.list()响应,查看下面的完整测试文件。

import moment from 'moment';
import sinon from 'auto-release-sinon';
import Promise from 'bluebird';
import ngMock from 'ng_mock';
import expect from 'expect.js';
import _ from 'lodash';

import '../watchersController';

describe('watchersController', function () {
  let $httpBackend;
  let $scope;
  let $route;
  let Watcher;

  const init = function () {
    ngMock.inject(function ($rootScope, $controller, _$httpBackend_, _$route_, _Watcher_) {
      $scope = $rootScope;
      $route = _$route_;
      $httpBackend = _$httpBackend_;
      Watcher = _Watcher_;

      sinon.stub(Watcher, 'list', () => {
        return Promise.resolve([
          { id: '123' },
          { id: '456' }
        ]);
      });

      $route.current = {
        locals: {
          currentTime: moment('2016-08-08T11:56:42.108Z')
        }
      };

      $controller('WatchersController', {
        $scope,
        $route,
        $uibModal: {}
      });

      $scope.$apply();

    });
  };

  beforeEach(function () {
    init();
  });

  afterEach(function () {
    $httpBackend.verifyNoOutstandingExpectation();
    $httpBackend.verifyNoOutstandingRequest();
  });

  it('watchers have been loaded', function () {
    expect($scope.watchers.length).to.equal(2);
  });

});
javascript angularjs sinon
3个回答
0
投票

在承诺解决后,您需要致电$scope.$apply。这样的事情应该可以解决问题

import moment from 'moment';
import sinon from 'auto-release-sinon';
import ngMock from 'ng_mock';
import expect from 'expect.js';
import _ from 'lodash';

import '../watchersController';

describe('watchersController', function () {
  let $httpBackend;
  let $scope;
  let $route;
  let Watcher;
  let deferred;

  const init = function () {
    ngMock.inject(function ($rootScope, $controller, _$httpBackend_, _$route_, _Watcher_, _$q_) {
      $scope = $rootScope;
      $route = _$route_;
      $httpBackend = _$httpBackend_;
      Watcher = _Watcher_;
      deferred = _$q_.defer(); // create a deferred

      // let stub return a promise to be resolved later
      sinon.stub(Watcher, 'list', () => deferred.promise);

      $route.current = {
        locals: {
          currentTime: moment('2016-08-08T11:56:42.108Z')
        }
      };

      $controller('WatchersController', {
        $scope,
        $route,
        $uibModal: {}
      });

    });
  };

  beforeEach(function () {
    init();
  });

  afterEach(function () {
    $httpBackend.verifyNoOutstandingExpectation();
    $httpBackend.verifyNoOutstandingRequest();
  });

  it('watchers have been loaded', function () {
    deferred.resolve([
          { id: '123' },
          { id: '456' }
    ]) // resolve deferred with mock data

    $scope.$apply(); // apply changes
    expect($scope.watchers.length).to.equal(2);
  });

});

此外,您可能希望通过在另一个测试中调用deferred.reject来检查控制器句柄拒绝拒绝。


0
投票

在承诺结束之前,您正在阅读列表。实际上你的过程如下:

  • 导入带有promise的类
  • 读取变量(尚未填充)
  • 测试它的价值

请看以下示例:

function MockedClass() {
	
  var _list = Promise.resolve([
          { id: '123' },
          { id: '456' }
        ]);
        
  var _watchersList = null;
  var _self = this;
  
	this.fillList = function() {
  	_list.then(function(response){
      _self.watchersList = response;
    });
  }
  
  this.getList = function() {
  	return self._watchersList;
  }
}

(function testPromise() {
    console.log("Start");
    
    var p1 = Promise.resolve([
          { id: '123' },
          { id: '456' }
        ]);
    
    var mockedClass = new MockedClass();
    console.log("The list isn't ready: ", mockedClass.getList());
    mockedClass.fillList();
    console.log("The list isn't yet ready: ", mockedClass.getList());
    
    console.log("End");
})();

在上面的例子中,我们应该等待从getList()方法返回的值。

因此,为了实现这一点,我们可以创建一个函数,试图读取从qazxsw poi方法返回的值,它仍然可以进行最多十次尝试。

请参阅以下工作示例:

getList()

我希望它可以帮助你,再见。


0
投票

我们可以通过在var attempts = 0; function MockedClass() { var _list = Promise.resolve([ { id: '123' }, { id: '456' } ]); var _watchersList = null; var _self = this; this.fillList = function() { _list.then(function(response){ _self.watchersList = response; }); } this.getList = function() { return _self.watchersList; } } (function testPromise() { console.log("Start"); var p1 = Promise.resolve([ { id: '123' }, { id: '456' } ]); var mockedClass = new MockedClass(); console.log("The list isn't ready: ", mockedClass.getList()); mockedClass.fillList(); onListReady(mockedClass, function(){ console.log("The list is ready: ", mockedClass.getList()); }); console.log("End"); })(); function onListReady(mockedClass, callback) { attempts++; if(mockedClass.getList()===undefined && attempts<=10) { console.log("waiting... attempt: " + attempts); setTimeout(function(){onListReady(mockedClass, callback)}, 50); } else { callback(); } }承诺之后在浏览器Callback Queue中推送它来延迟测试函数的执行,例如,使用Watcher.list()

setTimeout

现在,在从回调队列返回 it('watchers have been loaded', function (done) { setTimeout(function () { // catch promise response expect($scope.watchers.length).to.equal(2); done(); }); }); promise之后执行测试。

Watcher.list()工作的例子:

setTimeout

console.log('Hi'); setTimeout(function cb1() { console.log('cb1'); }, 5000); console.log('Bye');

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.