Jest测试用户注册Controller报错:response.status(...).json不是函数
问题排查:Node.js 16 + Jest测试时出现
response.status(...).json is not a function错误 核心错误原因
你的测试代码中,mockResponse.status的mock实现返回的是数值200,但Express的response.status()方法本身会返回response对象,以此支持链式调用.json()。现在返回数字的话,后续调用.json()自然会报错——因为数字类型没有这个方法。
分步修复方案
1. 修正mockResponse的status方法实现
把status的mock改成返回mockResponse对象本身,让链式调用能正常工作:
let mockResponse: Partial<Response> = { statusCode: 200, // 关键修改:返回当前mock对象,支持链式调用 status: jest.fn().mockReturnThis(), json: jest.fn().mockImplementation((result) => { responseObject = result }) }
2. 修复Controller中的语法与逻辑问题
- createQuery语法错误:原代码的定义不符合TS语法,修正为对象字面量:
// 原错误代码 // const createQuery = (username: username,hash:hash) // 修正后 const createQuery = { username, hash } - 分支未终止执行:
if(!username || !password)和if(user)分支没有加return,会导致代码继续执行后续逻辑,补充return避免异常:if(!username || !password){ return response.status(400).json({success:false, message: 'no username or password'}) } // ... if(user){ return response.status(400).json({message: 'User exists'}) }
3. 修正HashUtil的mock逻辑
你当前创建hashUtility实例后再spy,但Controller里会重新创建新的HashUtil实例,导致spy不生效。直接mock整个HashUtil类:
// 替换你的spy代码,路径替换为HashUtil的实际文件路径 jest.mock('./HashUtil', () => { return jest.fn().mockImplementation(() => { return { createHash: jest.fn().mockReturnValue({ hash: 'ddh44500000' }) } }) })
4. 对齐User.findOne的mock对象
测试代码里写的是UserConfig.findOne,但Controller里用的是User.findOne,修正为一致:
User.findOne = jest.fn().mockResolvedValue(null)
完整修正后的测试代码示例
describe('UserAuthController test suite', ()=>{ let authController:AuthenticationController beforeEach(()=>{ authController = new AuthenticationController() }) // 提前mock HashUtil类 jest.mock('./HashUtil', () => { return jest.fn().mockImplementation(() => { return { createHash: jest.fn().mockReturnValue({ hash: 'ddh44500000' }) } }) }) it('should successfully register a new user ', async ()=>{ let mockRequest = { body: { username: 'user@gmail.com', password: 'mypassword' } } let responseObject = {}; let mockResponse: Partial<Response> = { statusCode: 200, status: jest.fn().mockReturnThis(), json: jest.fn().mockImplementation((result) => { responseObject = result }) } // 修正为User.findOne,用mockResolvedValue处理异步 User.findOne = jest.fn().mockResolvedValue(null) User.create = jest.fn().mockResolvedValue({}) let next = jest.fn() await authController.registerNewUser(mockRequest as Request, mockResponse as Response, next) // 可添加断言验证行为是否符合预期 expect(mockResponse.status).toHaveBeenCalledWith(200) expect(mockResponse.json).toHaveBeenCalledWith({ username: 'user@gmail.com', hash: 'ddh44500000' }) }) })
内容的提问来源于stack exchange,提问作者BreenDeen
相关产品推荐
相关产品推荐

