简体   繁体   中英

Testing REST API in Express NodeJS

I need to be mocking the REST API developed in NodeJS / Express. I am already using Jest and have tried using Supertest / Nock for API testing. From my understanding, Supertest will call the actual API and not just mock it. I don't want this as it would create entries in DB etc.

I tried using Nock and seems to be what I need but the issue is I am referencing the "req" and "res" objects in the route handler, which is coming as undefined when calling the handlers alone during testing.

Code: server.js

app.get("/api/user/:id/movies",testHander)

testHander.js

const axios = require("axios");

const testHander = async (req,res) =>{
    let id = req.params.id;
    const data = await axios.get(`http://backendServerURL/user/${id}/movies`)
    return res.send(data);
}

testing.test.js

const nock = require("nock");
const testHander = require("../handler/testHander");

describe("Test Handler", () => {
  it("should return user movies", () => {
    const id = 1;

    nock("http://someRandomURL")
      .get(`/user/${id}/movies`)
      .reply(200, { data: { movies: [{ name: "Avengers", year: "2019" }] } });

    const response = await testHander();

    expect(response.data).toBe("someExpectation")
  });
});

Question: How should I test this code, by mocking the backendServerUrl?

so I would drop the nock as you can mock out axios with jest , and it looks like you're already using that, no need to import another module.

scratch.js

const axios = require('axios')

module.exports.handler = async (req, _) => {
    const { id } = req.params
    const data = await axios.get(`http://backendServerURL/user/${id}/movies`)

    return data
}

scratch.test.js

jest.mock('axios')

const axios = require('axios')
const { handler } = require('../scratch')

it('should return mock movie data from axios get request', async () => {
    const id = 8238010
    const mockMovie = { data: { movies: [{ name: 'Avengers', year: '2019' }] } }
    const mockRequest = { params: { id } }

    axios.get.mockResolvedValue(mockMovie)

    const response = await handler(mockRequest)

    expect(axios.get).toHaveBeenCalledTimes(1)
    expect(axios.get).toHaveBeenCalledWith(`http://backendServerURL/user/${id}/movies`)
    expect(response).toEqual(mockMovie)
})

axios returns a promise so we're going to use the mockResolvedValue over mockReturnedValue , and we want to mock out the get only, and this is what we are going to make our assertions against.

Here are some useful resources for the future: https://jestjs.io/docs/en/mock-functions.html https://jestjs.io/docs/en/expect

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM