如何在Jest Node.js中Mock带lean与不带lean的Mongoose find方法
适配Mongoose
find() 和 find().lean() 的Jest Mock方案 方案一:简单模拟可await对象
Mongoose的find()返回的Query对象本身支持直接await(因为实现了then方法),之前的mock只处理了lean()的情况,没让返回对象支持await。给mock对象加上then方法,同时让lean()返回自身就能解决问题:
// resultValueMockFind 是你预设的模拟返回数据 mockMongooseFind.mockImplementation(() => { const mockQuery = { // 让对象支持await,直接返回预设数据 then: (resolve) => resolve(resultValueMockFind), catch: (reject) => reject() }; // lean方法返回这个可await的对象本身 mockQuery.lean = jest.fn().mockReturnValue(mockQuery); return mockQuery; });
这样不管是await ModelA.find()还是await ModelA.find().lean(),都能拿到你预设的resultValueMockFind。
方案二:支持链式调用的Mock(适配更多场景)
如果你的代码里还用到了sort、limit这类Query链式方法,用这个方案更灵活,能模拟完整的Query行为:
// 封装一个生成Mock Query的工具函数 const createMockQuery = (mockData) => { const mockQuery = { // 支持await then: jest.fn((resolve) => resolve(mockData)), catch: jest.fn((reject) => reject()), // 链式方法都返回自身,支持连续调用 lean: jest.fn().mockReturnThis(), sort: jest.fn().mockReturnThis(), limit: jest.fn().mockReturnThis() // 需要其他方法的话直接加在这里就行,比如skip、populate }; return mockQuery; }; // 给find方法绑定mock实现 mockMongooseFind.mockImplementation(() => createMockQuery(resultValueMockFind));
原写法问题说明
之前的mock只返回了带lean方法的普通对象,这个对象没有实现可await的接口(也就是没有then方法),所以直接await的时候,JS不会把它当作异步处理,自然返回的就是那个包含lean mock函数的对象,而不是你要的数据。
内容的提问来源于stack exchange,提问作者Nico
相关产品推荐
相关产品推荐

