据我了解,使用await
方法( thenable )then
来对象只是调用then
方法。我无法通过玩笑来使它起作用:
test('test thenable', async () => {
const thenable = {
then: () => 1
};
const actual = await thenable;
expect(actual).toEqual(1);
});
这会引发一个开玩笑的错误:
超时-在jest.setTimeout.Error指定的5000ms超时内未调用异步回调
是否可以通过异步测试 thenable 对象?
我正在尝试测试已配置的knex querybuilder。我正在测试的代码是这样的:
const query = db('my_table')
.where('key', 'someValue')
.select('key', 'value');
const results = await query;
db
变量是一个已配置的Knex对象,用于标识客户端和配置。
因此,db
是使用where
和select
方法返回对象的函数,并且它必须具有then
方法,因此可以await
编辑。至少我是这样理解它的。
答案 0 :(得分:0)
这是一个解决方案,例如,我们在findById
类中有一个SomeDaoImpl
方法,并在该方法中使用了knex
查询构建器。我使用IKnex
界面来模拟knex
查询构建器的真实界面。
index.ts
:
interface IKnex {
where(...args: any): any;
raw(...args: any): any;
select(...args: any): any;
then(): any;
}
class SomeDaoImpl {
private knex: IKnex;
constructor({ knex }) {
this.knex = knex;
}
public findById(id: string) {
return this.knex.where({ id }).select();
}
}
export { SomeDaoImpl, IKnex };
您可以模拟knex
查询构建器的链接方法,如下所示:
index.spec.ts
:
import { SomeDaoImpl, IKnex } from './';
const knexMocked: jest.Mocked<IKnex> = {
where: jest.fn().mockReturnThis(),
raw: jest.fn().mockReturnThis(),
select: jest.fn().mockReturnThis(),
then: jest.fn().mockReturnThis()
};
const someDaoImpl = new SomeDaoImpl({ knex: knexMocked });
describe('SomeDaoImpl', () => {
it('t1', async () => {
(knexMocked.where() as jest.Mocked<IKnex>).select.mockResolvedValueOnce('mocked data');
const actualValue = await someDaoImpl.findById('1');
expect(actualValue).toBe('mocked data');
expect(knexMocked.where).toBeCalledWith({ id: '1' });
expect(knexMocked.where().select).toBeCalledTimes(1);
});
});
单元测试结果:
PASS src/stackoverflow/57811289/index.spec.ts
SomeDaoImpl
✓ t1 (12ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 3.033s
完整的演示在这里:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/57811289
答案 1 :(得分:0)
是的,Jest
可以使用async
测试 thenable 对象。
then
函数应接受success
回调,还可以接受error
回调。
当前编写代码的方式then
不接受任何参数,因此它永远不会调用success
回调...因此它永远不会解析,await
会继续等待直到测试超时。
要解决此问题,只需添加一个success
参数并使用已解析的值对其进行调用:
test('test thenable', async () => {
const thenable = {
then: success => { success(1); }
};
const actual = await thenable;
expect(actual).toEqual(1); // Success!
});