我的jest测试在我的控制器上失败,出现了一个json方法缺失错误。

huangapple go评论58阅读模式
英文:

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: &quot;msg&quot; });

In order to be able to call .json({ message: &quot;msg&quot; }) the previous status method must return this (the response object).

But in you're test code you've the following:

let mockResponse: Partial&lt;Response&gt; = {
  statusCode: 200,
  status: jest.fn().mockImplementation(() =&gt; 200),
  json: jest.fn().mockImplementation((result) =&gt; {
    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(() =&gt; 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) =&gt; mockResponse),
  json: jest.fn().mockImplementation((result) =&gt; {
    responseObject = result;
    return mockResponse
  }),
};

huangapple
  • 本文由 发表于 2023年5月29日 07:05:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/76353913.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定