-1

I have a simple express application and i want to fully be able to mock it, here's what i've got so far

userRoute.js

const express = require("express")
const router = express.Router()
const db = require('./db')

router.get("/users/", async (req, res) => {
  res.json({
    status: 200,
    data: await db.getUsers(),
  })
})

module.exports = router

My issue is i am trying to mock the db.getUsers function but not sure how

here is my test code:

const router = require("./userRoute.js")

const app = new express()
app.use("/", router)

describe("Users Route", () => {
  test("getUsers Happy Path", async () => {
    jest.spyOn(db, "getUsers").mockImplementation(() => {
      return {
         id:12345
         name: "Jason"
         age: "34"
       }
    })

    const res = await app.get("/users/")
    console.log(res)
  })
})

this doesn't work for me, if i run the function regularly in a standard function it works but since its an api endpoint in a route it doesn't work for whatever reason, any help would be fantastic

beep
  • 41
  • 3
  • I don't think there is any easy way of mocking the db.getUsers because of the way you're using it in the router. Notice that you're importing the db module in the userRoute.js file and using it direclty, so when you import the router in your test file, your router already have the db module with real implementation, which is not affected by your attempt to mock it. The best approach would be trying to find a way to pass the database to the router. I found an article that may help to understand better and find a solution: https://sammeechward.com/mocking-a-database-with-jest-in-javascript/ – Eduardo Sep 14 '22 at 14:43

1 Answers1

1

Maybe you want to try to mock the db before require the useRouter.js

Also, you need to run the server (and close it after all tests) and make a real request to your server.

const express = require('express');
const axios = require('axios');
const PORT = 5565;

const userMock = {
  id: 1,
  name: 'John Doe',
  email: 'email@email.com',
}
const dbSpy = jest.spyOn(require('./db.js'), 'getUsers').mockImplementation(() => userMock);

const router = require('./index.js');

const app = express();

app.use('/', router);

const server = app.listen(PORT, () => 'Example app listening on port 3000!');

describe('Users Route', () => {
  afterAll(() => server.close());
  test('getUsers Happy Path', async () => {
    const response = await axios.get(`http://localhost:${PORT}/users/`);      

    expect(dbSpy).toHaveBeenCalledTimes(1);
    expect(response.status).toBe(200);
    expect(response.data.data).toEqual(userMock);
  });  
})
Carlos
  • 61
  • 2
  • 1
    Hi, did this work for you? Thanks for the answer im trying it now – beep Sep 15 '22 at 09:26
  • 1
    Thank you this worked for me immediately, the mocking of the db and function before importing the route made all the difference – beep Sep 15 '22 at 09:32