Search code examples
javascriptnode.jsjestjssupertest

How to store response body in supertest?


I am testing very basic REST api with supertest. I want to save the item id received in response body and assign it to a variable. Using this id i want to make further tests like get-item-by-id or update-item-by-id. No official documentation has covered this so a beginner friendly answer would be very helpful.

test i have written

const request = require("supertest")
let id;

describe('Products API', () => {
    it('GET  /products --> array of products', async () => {
        return request('http://localhost:3001')
            .get('/api/products')
            .expect(200)
            .expect('Content-Type', /json/)
            .then(response => {
                expect(response.body).toEqual(
                    expect.objectContaining({
                        success: true,
                        data: expect.any(Array)
                    })
                )
            })
    })

})


Solution

  • Use regular JS variables

    const request = require("supertest")
    
    describe('Products API', () => {
        it('GET  /products --> array of products', async () => {
            return request('http://localhost:3001')
                .get('/api/products')
                .expect(200)
                .expect('Content-Type', /json/)
                .then(response => {
                    expect(response.body).toEqual(
                        expect.objectContaining({
                            success: true,
                            data: expect.any(Array)
                        })
                    )
                    const data = response.body.data;
    
                    expect(data.length).toBeGreaterThan(0)
    
                    data.forEach(product => {
                        let id = product.id;
                        // expect data about the products
                    }) 
                })
        })
    
    })
    

    want to make further tests like get-item-by-id or update-item-by-id

    You should explicitly test those endpoints, not via GET /api/products

    E.g.

    it('POST /products/{id} --> Updates a product', async () => {
      const id = 1;
      const result = request('http://localhost:3001')
        .post(`/api/products/${id}`)
        ...
    
      // TODO: Check the product was actually updated in the database, for example
    });
    

    More importantly, don't (or try not to) store variable state between tests.