AngularJS单元测试:使用async/await与Jasmine



我正在尝试在下面相应的(Jasmine(单元测试中使用async/await关键字对我的Angular服务进行单元测试。原生Promise的测试工作得很好,但我几乎坚持让 Angular$q对应物工作。

  • 角度:1.6.5
  • 茉莉花:2.7.0
  • MacOS上的(无头(Chrome:60.x

angular
.module('asyncAwaitTest', [])
.factory('xService', xServiceFactory);
function xServiceFactory(
$q,
$timeout
) {
return {
getXAfter1Sec() {
return new Promise(resolve => setTimeout(() => resolve(43), 1000));
},
getXAfter1SecWithAngular$Q() {
const deferred = $q.defer();
$timeout(() => deferred.resolve(43), 1000);
return deferred.promise;
}
};
}
jasmine.DEFAULT_TIMEOUT_INTERVAL = 2000;
describe('asyncAwaitTest: x service', () => {
let $timeout;
let xService;
beforeEach(() => {
module('asyncAwaitTest');
inject(
(
_$timeout_,
_xService_
) => {
$timeout = _$timeout_;
xService = _xService_;
}
);
});
it('should work', async (done) => {
const x = await xService.getXAfter1Sec();
expect(x).toEqual(43);
done();
});
it('should work, too. but y not?!!', async (done) => {
const xPromise = xService.getXAfter1SecWithAngular$Q();
$timeout.flush();
const x = await xPromise;
expect(x).toEqual(43);
done();
});
});

这里提供的小提琴:https://jsfiddle.net/glenn/gaoh6bvc/

我试过谷歌,但它并没有给我一个显着的好线索 😞

您可以为测试创建一个帮助程序,将承诺从$q转换为本机承诺。在这里查看。

it('should work, too. but y not?!!', async (done) => {
const xPromise = toNativePromise(xService.getXAfter1SecWithAngular$Q());
$timeout.flush();
const x = await xPromise;
expect(x).toEqual(43);
done();
});
function toNativePromise(promise) {
return new Promise((resolve, reject) => {
promise.then(val => {
resolve(val);
}, err => {
reject(err);
});
});
}

async函数基于原生承诺,而AngularJS使用$q承诺。await是一种语法糖,用于将承诺与then联系起来。$q承诺链在测试中以摘要形式执行。

不能

await xPromise;
$rootScope.$digest();

因为在执行$rootScope.$digest()之前不会评估$rootScope.$digest()。这会导致未决承诺。

AngularJS首先不应该用async..await进行测试。Angular被设计为同步测试。

是的

it('...', () => {
...
xPromise.then(x => {
expect(x).toEqual(43);
});
$rootScope.$digest();
});

或者承诺可以用jasmine-promise-matchers扁平化:

it('...', () => {
...
expect(xPromise).toBeResolvedWith(43);
$rootScope.$digest();
});

最新更新