我有一个 ES6 / Aurelia 应用程序,我正在使用 jasmine 来测试。我试图测试的方法看起来像这样:
update() {
let vm = this;
vm.getData()
.then((response) => {
vm.processData(response);
});
}
其中
this.getData
是一个返回 Promise 的函数。
我的规格文件看起来像这样:
describe('my service update function', () => {
it('it will call the other functions', () => {
myService = new MyService();
spyOn(myService, 'getData').and.callFake(function() {
return new Promise((resolve) => { resolve(); });
});
spyOn(myService, 'processData').and.callFake(function() { return; });
myService.update();
// this one passes
expect(myService.getData).toHaveBeenCalled();
// this one fails
expect(myService.processData).toHaveBeenCalled();
});
});
我明白为什么会失败 - 承诺是异步的,并且在达到预期时尚未解决。
如何推动测试中的承诺解决,以便我可以测试回调中的代码?
失败测试的jsfiddle:http://jsfiddle.net/yammerade/2aap5u37/6/
我通过返回一个行为类似承诺而不是实际承诺的对象来运行解决方法
describe('my service update function', () => {
it('it will call the other functions', () => {
myService = new MyService();
spyOn(myService, 'getData').and.returnValue({
then(callback) {
callback();
}
});
spyOn(myService, 'processData').and.callFake(function() { return; });
myService.update();
// this one passes
expect(myService.getData).toHaveBeenCalled();
// this one fails
expect(myService.processData).toHaveBeenCalled();
});
});
在这里摆弄:http://jsfiddle.net/yammerade/9rLrzszm/2/
这样做有什么问题吗?
it((done) => {
// call done, when you are done
spyOn(myService, 'processData').and.callFake(function() {
expect(myService.processData).toHaveBeenCalled();
done();
});
})
添加@yammerade 的答案
我们可以创建一个行为类似于 Promise 的假对象,而不是返回实际的 Promise。以下代码还允许链接
.then(...).catch(...)
class MockPromise {
constructor(data, err) {
this.data = data;
this.err = err;
}
then(callback) {
callback(this.data);
return this;
}
catch(callback) {
callback(this.err);
return this;
}
};
var promise = new MockPromise('resolved data here', 'resolved error here');
// resolve your promises like normal
promise.then(function(data) {
...
}).catch(function(err) {
...
});
当您想在 Jasmine Spy Obj 中测试回调逻辑时,这会很有帮助