我有这项服务:
angular.module('domeeApp')
.factory('streamWidget', streamWidgetFactory);
function streamWidgetFactory($q) {
return {
loadContent: function() {
return $q(function(resolve, reject) {
resolve('test');
})
}
}
}
我用karma / mocha / chai测试它:
describe('streamWidget', function() {
beforeEach(module('domeeApp'));
var streamWidget;
var $timeout;
beforeEach(inject(function(_$timeout_, _streamWidget_) {
streamWidget = _streamWidget_;
$timeout = _$timeout_;
}));
it('should load new content', function(done) {
streamWidget.loadContent()
.then(function(res) {
expect(res).to.equal('test');
done();
})
.catch(function(){})
$timeout.flush();
});
});
由于$ q承诺在跟随this answer之后不能与mocha一起使用,{{3}}表示添加$timeout.flush()
以强制承诺的.then
方法被执行。
问题是,在调用.flush()之后,我的所有应用程序都醒来了,我开始从角度模拟中得到这个错误:
Error: Unexpected request: GET /partials/page/view/index
。
我知道$ httpBackend,但是疯狂来模拟我的应用在启动时发出的所有请求。
有没有办法让$q
承诺可以在不调用$timeout.flush()
或$rootScope.$apply()
的情况下使用mocha?
答案 0 :(得分:1)
如图here所示,chai-as-promised
可用于声明$q
承诺。
使用此设置
chaiAsPromised.transferPromiseness = function (assertion, promise) {
assertion.then = promise.then.bind(promise);
if (!('$$state' in promise))
return;
inject(function ($rootScope) {
if (!$rootScope.$$phase)
$rootScope.$digest();
});
};
摘要周期将在promise断言上自动触发,执行整个promise链。
在这种情况下,规范
it('...', () => {
...
expect(...).to.eventually...;
expect(...).to.eventually...;
$rootScope.$digest();
});
可以省略$digest()
来电并成为
it('...', () => {
...
expect(...).to.eventually...;
expect(...).to.eventually...;
});
请注意,$q
承诺是同步的,不应该从Mocha规范返回,也不应调用done
回调。
答案 1 :(得分:0)
这是我们使用的另一种策略,因为我们从不实际上需要$httpBackend
,但它有时(随机)无法对指令使用的模板进行请求(即使这些模板在$templateCache
)中可用:
beforeEach(function() {
module('app', function($provide) {
// This is using jasmine, but the idea is the same with mocha.
// Basically just replace $httpBackend with a function that does nothing.
$provide.constant('$httpBackend', jasmine.createSpy('$httpBackend'));
});
});
当然,如果您在其他情况下实际使用 $httpBackend
,那么这将无法正常工作,因为您需要它来模拟响应对象。