I have been trying for several hours to test an endpoint of my rest api with Jest, Supertest and Express.
This endpoint is protected by an authentication middleware named "advancedAuthGuard
".
So I'm trying to mock this middleware in order to skip authentication check for endpoints testing
//./router.js
router.get('/route1', advancedAuthGuard(false), controller);
Important: advancedAuthGuard
is a middleware that accepts configuration argument ( curried middleware )
//./middleware/advancedAuthGuard.js
const advancedAuthGuard = (additionalCondition) => (req,res,next) => {
//Check authentication logic ...
const isAuth = true
if (isAuth && !additionalCondition)
next()
else
next(new Error('Please auth'))
}
When I run the following test to check if I get status code '200' . The test fail before run.
//./test.js
import supertest from "supertest"
import app from './app.js'
import { advancedAuthGuard } from "./middlewares/advancedAuthGuard";
jest.mock("./middlewares/advancedAuthGuard")
const request = supertest(app)
beforeEach(()=>{
jest.clearAllMocks()
})
it("should '/route1' respond with 200 status", async ()=>{
const mockedMiddleware = jest.fn().mockImplementation((res, req, next)=> next() )
advancedAuthGuard.mockReturnValue(mockedMiddleware)
const res = await request.get("/route1")
expect(res.status).toEqual(200)
})
I get the following error:
Test suite failed to run
Route.get() requires a callback function but got a [object Undefined]
> 10 | router.get('/route1', advancedAuthGuard(false), controller);
| ^
I therefore deduce that the problem comes from the mock...
And when I debug it via console.log, I realize that I get an incomplete mock :
- I was able to verify that the mock of function (
advancedAuthGuard(false)
) was present - But this mock should return a second mock of type
function (req,res,next){}
, however it only returns undefined
I also noticed that:
- This mock issue only occurs with curried middlewares (middleware with input parameters)
- This mock issue only occurs when the curried middleware is executed in express router. (When I tried the mock outside express router, the mock appears correctly)
So I would like to know why it is impossible for me to mock a curried middleware ( middleware with argument ) used in an Expressjs endpoint with Jest and Supertest.
Here is a github link with minimal express, jest, supertest config, where you can reproduce this problem, by running the test.js
file. https://github.com/enzo-cora/jest-mock-middleware