如何用Jest断言TypeORM Brackets?测试报错解决方法
如何为TypeORM Brackets的查询逻辑编写单元测试?
业务代码示例
你项目中使用TypeORM Brackets的查询代码如下:
const getQuery = this.repository.createQueryBuilder("user"); const brackets = new Brackets((qb) => { qb.where("user.name ~* :name", { name: "aaa" }); qb.orWhere("user.name ~* :name", { name: "bbb", }); }); getQuery.andWhere(brackets); const result = await getQuery.getMany();
遇到的问题
你尝试直接断言andWhere的调用参数为某个Brackets实例:
expect(repository.andWhere).toHaveBeenNthCalledWith(new Brackets((qb) => { qb.where("user.name ~* :name", { name: "aaa" }); qb.orWhere("user.name ~* :name", { name: "bbb", }); }));
运行测试时出现错误:TypeError: qb.where is not a function,无法完成正确测试。
解决方案
核心思路
Brackets的核心是内部的回调函数——当QueryBuilder执行时,才会调用这个回调并传入真实的QueryBuilder实例。直接比较Brackets实例没有意义(每个实例都是新对象,匿名函数引用不同),正确的做法是模拟QueryBuilder对象,跟踪其方法调用,并手动触发Brackets回调验证逻辑。
具体测试代码(以Jest为例)
- 模拟Repository和QueryBuilder
// 模拟QueryBuilder,链式调用需要返回自身 const mockQueryBuilder = { where: jest.fn().mockReturnThis(), orWhere: jest.fn().mockReturnThis(), andWhere: jest.fn().mockReturnThis(), getMany: jest.fn().mockResolvedValue([]) }; // 模拟Repository,createQueryBuilder返回上面的Mock const mockRepository = { createQueryBuilder: jest.fn().mockReturnValue(mockQueryBuilder) }; // 假设你的业务逻辑封装在UserService中 const userService = new UserService(mockRepository as any);
- 调用业务方法
// 调用包含目标查询逻辑的方法 await userService.getFilteredUsers();
- 验证调用逻辑
// 验证createQueryBuilder的调用 expect(mockRepository.createQueryBuilder).toHaveBeenCalledWith("user"); // 获取andWhere传入的Brackets实例 const bracketsInstance = mockQueryBuilder.andWhere.mock.calls[0][0]; // 手动执行Brackets的回调,传入Mock的QueryBuilder bracketsInstance._callbacks[0](mockQueryBuilder); // 验证回调内的where/orWhere调用是否符合预期 expect(mockQueryBuilder.where).toHaveBeenCalledWith("user.name ~* :name", { name: "aaa" }); expect(mockQueryBuilder.orWhere).toHaveBeenCalledWith("user.name ~* :name", { name: "bbb" }); // 验证最终执行了getMany expect(mockQueryBuilder.getMany).toHaveBeenCalled();
错误原因说明
- 直接断言Brackets实例无法匹配:每个
new Brackets()都是独立对象,Jest无法通过引用匹配两个看似相同的实例。 qb.where is not a function报错:断言时创建的Brackets回调从未被执行,且Jest不会自动模拟回调中的qb对象,导致调用qb.where时找不到方法。
内容的提问来源于stack exchange,提问作者Chun Young
相关产品推荐
相关产品推荐

