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);
});
});
在承诺解决后,您需要致电$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
来检查控制器句柄拒绝拒绝。
在承诺结束之前,您正在阅读列表。实际上你的过程如下:
请看以下示例:
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()
我希望它可以帮助你,再见。
我们可以通过在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');