我正在使用Jasmine编写一些测试用例。它看起来像这样:
班级定义:
class Person {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
getFullName() {
return this.firstName + this.lastName;
}
getName () {
setTimeout(() => {
return this.getFullName();
}, 100)
}
}
module.exports = Person;
测试代码:
const Person = require('./index');
describe('Test Person methods', () => {
beforeEach(() => {
programmer = new Person('John', 'Gray');
spyOn(programmer, 'getFullName');
programmer.getName();
});
it('getName should call getFullName', () => {
expect(programmer.getFullName).toHaveBeenCalled();
})
});
getName
是一个异步函数,在一段时间后会调用getFullName
。由于这种异步性质,it
规范在调用getName
后立即执行,因此测试失败。
我知道我可以使用Jasmine的done
函数来执行异步测试,但我不知道如何在这里实现它?在文档中,done
方法仅在异步代码中调用,但测试无法访问该代码,因为它由getName
方法在内部处理。
或者有没有其他方法不使用done
方法?
Here是此代码的工作示例。
答案 0 :(得分:0)
我认为你需要将done
参数传递给函数并调用它:
beforeEach((done) => {
someObj = new SomeClass();
spyOn(someObj, 'onSuccess');
someObj.start();
done();
});
it('start should call onSuccess', (done) => {
expect(someObj.onSuccess).toHaveBeenCalled();
done();
});
答案 1 :(得分:0)
您对getName
的实施是错误的。在javascript中,要处理异步函数的结果,您需要将callback传递给异步函数或返回Promise。一旦修复了实现,那么测试它应该很简单:
使用回调方法:
getName (callback) {
setTimeout(() => {
callback(this.getFullName());
}, 100)
}
beforeEach(done => {
...
programmer.getName(name => {
done(); // at this point the async func. has completed
});
});
使用承诺:
getName () {
return new Promise(resolve => {
setTimeout(() => {
resolve(this.getFullName());
}, 100)
})
}
beforeEach(done => {
...
programmer
.getName()
.then(name => {
done(); // at this point the async func. has completed
});
});
修改强>
如果你正在使用Promise,你也可以使用async / await(Jasmine> = 2.7):
beforeEach(async () => {
...
const name = await programmer.getName();
// async func has completed here.
// await acts like .then() and "waits" for your promise to resolve
// done wouldn't be needed because there aren't any callbacks
});