AngularJS 1.4.8
加载视图时,我在控制器中执行了以下方法。 Watcher
是注入控制器的工厂。方法.list()
返回bluebird promise。
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);
});
});
答案 0 :(得分: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
来检查控制器处理承诺拒绝。
答案 1 :(得分:0)
我们可以在Watcher.list()
承诺后在浏览器回调队列中推送测试功能,例如,使用setTimeout:
it('watchers have been loaded', function (done) {
setTimeout(function () { // catch promise response
expect($scope.watchers.length).to.equal(2);
done();
});
});
现在,在从回调队列返回Watcher.list()
承诺后执行测试。
setTimeout
工作的示例:
console.log('Hi');
setTimeout(function cb1() {
console.log('cb1');
}, 5000);
console.log('Bye');
答案 2 :(得分: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();
console.log("The list isn't yet ready: ", mockedClass.getList());
console.log("End");
})();
在上面的示例中,我们应该等待从getList()
方法返回的值。
因此,为了实现这一点,我们可以创建一个函数,尝试读取从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();
}
}
我希望它可以帮助你,再见。