英文:
My jest test is failing for my controller with a json method missing error
问题
我有一个注册用户的控制器,但是测试不起作用。我在Node版本16中使用Jest。这是控制器:我得到以下错误
TypeError: response.status(...).json is not a function
我确实实现了对象的json方法,所以我不知道为什么会出现这个错误
class AuthenticationController {
registerNewUser = async(request:Request, response:Response, next:NextFunction) =>{
const username = request.body.username
const password = request.body.password
if(!username || !password){
response.status(400).json({success:false, 'no username or password'})
}
const query = {username: username}
const user = await User.findOne(query)
if(user){
response.status(400).json({message: 'User exists'})
}
const hashUtility = new HashUtil()
const {hash} = hashUtility.createHash(password)
const createQuery = (username: username,hash:hash)
await User.create( createQuery)
// TypeError: response.status(...).json is not a function
// is now thrown here
response.status(200).json(createQuery)
}
}
export {AuthenticationController}
这是我的测试类
describe('UserAuthController test suite', ()=>{
let authController:AuthenticationController
beforeEach(()=>{
authController = new AuthenticationController()
})
it('should successfully register a new user ', async ()=>{
let user = new User({
username: 'user@gmail.com',
hash: 'ddh44500000',
})
let mockRequest = {
body: {
username: 'user@gmail.com',
password: 'mypassword'
}
}
let responseObject = {};
let mockResponse: Partial<Response> = {
statusCode: 200,
status: jest.fn().mockImplementation(()=>200),
json: jest.fn().mockImplementation((result) =>{
responseObject = result
})
}
UserConfig.findOne =
jest.fn().mockImplementation((query)=>{
return null
})
let next = jest.fn()
let hashUtility = new HashUtil()
jest.spyOn(hashUtility, 'createHash').mockImplementationOnce((password) =>{
return {hash: 'ddh44500000'}
})
await authController.registerNewUser(mockRequest as Request, mockResponse as
Response, next)
console.log(`ResponseObjeect ${responseObject}`)
})
})
我不知道我在测试代码中缺少什么。请帮忙
英文:
I have a controller that registers a user, however, testing it does not work. I am using Jest in Node version 16. Here is the controller: I get the following error
TypeError: response.status(...).json is not a function
I did implement the json method of the object so I don't know why I'm getting this error
class AuthenticationController {
registerNewUser = async(request:Request, response:Response, next:NextFunction) =>{
const username = request.body.username
const password = request.body.password
if(!username || !password){
response.status(400).json({success:false, 'no username or password'})
}
const query = {username: username}
const user = await User.findOne(query)
if(user){
response.status(400).json({message: 'User exists'})
}
const hashUtility = new HashUtil()
const {hash} = hashUtility.createHash(password)
const createQuery = (username: username,hash:hash)
await User.create( createQuery)
// TypeError: response.status(...).json is not a function
// is now thrown here
response.status(200).json(createQuery)
}
}
export {AuthenticationController}
Here is my test class
describe('UserAuthController test suite', ()=>{
let authController:AuthenticationController
beforeEach(()=>{
authController = new AuthenticationController()
})
it('should successfully register a new user ', async ()=>{
let user = new User({
username: 'user@gmail.com',
hash: 'ddh44500000',
})
let mockRequest = {
body: {
username: 'user@gmail.com',
password: 'mypassword'
}
}
let responseObject = {};
let mockResponse: Partial<Response> = {
statusCode: 200,
status: jest.fn().mockImplementation(()=>200),
json: jest.fn().mockImplementation((result) =>{
responseObject = result
})
}
UserConfig.findOne =
jest.fn().mockImplementation((query)=>{
return null
})
let next = jest.fn()
let hashUtility = new HashUtil()
jest.spyOn(hashUtility, 'createHash').mockImplementationOnce((password) =>{
return {hash: 'ddh44500000'}
})
await authController.registerNewUser(mockRequest as Request, mockResponse as
Response, next)
console.log(`ResponseObjeect ${responseObject}`)
})
})
I don't know what I'm missing in my test code. Please help
答案1
得分: 0
问题在于你没有正确创建你的 mockResponse
对象。
你的响应对象的方法应该支持方法链,就像你的代码中描述的那样:
response.status(200).json({ message: "msg" });
为了能够调用 .json({ message: "msg" })
,前一个 status
方法必须返回 this
(即 response
对象)。
但是在你的测试代码中,你有以下代码:
let mockResponse: Partial<Response> = {
statusCode: 200,
status: jest.fn().mockImplementation(() => 200),
json: jest.fn().mockImplementation((result) => {
responseObject = result;
}),
};
因此,当你将这个模拟响应对象传递给中间件,并且它调用 response.status(400)
时,它返回 200
(根据你的 jest.fn().mockImplementation(() => 200)
)。
然后它链接了 .json({})
调用,但由于前一个调用的返回值是 200
,所以 (200).json({...})
抛出了一个错误:
TypeError: response.status(...).json is not a function
这个问题很容易解决,你只需要在每个模拟方法中返回 mockResponse
对象,就像下面的代码片段一样:
let responseObject = {};
let mockResponse = {
statusCode: 200,
status: jest.fn().mockImplementation((status) => mockResponse),
json: jest.fn().mockImplementation((result) => {
responseObject = result;
return mockResponse
}),
};
英文:
The problem is that you're not creating your mockResponse
object properly.
You're response object's methods should support method chaining as described in your code:
response.status(200).json({ message: "msg" });
In order to be able to call .json({ message: "msg" })
the previous status
method must return this
(the response
object).
But in you're test code you've the following:
let mockResponse: Partial<Response> = {
statusCode: 200,
status: jest.fn().mockImplementation(() => 200),
json: jest.fn().mockImplementation((result) => {
responseObject = result;
}),
};
So, when you pass this mock response object to the middle-ware and it calls response.status(400)
it returns 200
(according to your jest.fn().mockImplementation(() => 200)
).
Then it chains the .json({})
call but as the returned value from previous call was 200
, so (200).json({...})
throws an error:
> TypeError: response.status(...).json is not a function
This is an easy fix, you just need to return the mockResponse
object from each mock methods, like the following snippet:
let responseObject = {};
let mockResponse = {
statusCode: 200,
status: jest.fn().mockImplementation((status) => mockResponse),
json: jest.fn().mockImplementation((result) => {
responseObject = result;
return mockResponse
}),
};
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论