DEV Community

Cover image for Packageless - It's time to reduce your dependencies: The Supertest case.
OliverOdo
OliverOdo

Posted on

Packageless - It's time to reduce your dependencies: The Supertest case.

Hey 👋,
Let me share this small snippet that I hope will make you think differently.

Are you not tired of Github security bot that yelling at you about potential security issue within your package-lock.json?

YES, YES, YES!
This is why I want to share my small snippets. It's time to reduce the amount of dependencies in your project.

The Supertest use case.

Supertest is a Popular library that is used to Unit Test HTTP Server.
However Supertest depends on other libraries:

  • superagent (11 dependencies)
  • methods (0 dependencies)

Do we really need it?

Let me share the small express app that we will use for our example:

const app = express()
  .use(express.json())
  .post('/users', (req, res) => {
    res.status(201).json({ id: 1, name: 'Joe' })
  })
Enter fullscreen mode Exit fullscreen mode

Supertest

Here an example on how we use super test to test a simple POST endpoint.

describe('[SUPERTEST] Http server Testing', () => {
  test('POST /users (201)', async () => {
    const response = await supertest(app)
      .post('/users')
      .send({name: 'Joe'})
    expect(response.status).toBe(201)
    const expectedBody = {
      id: 1,
      name: 'Joe'
    }
    expect(response.body).toEqual(expectedBody)
  })
})
Enter fullscreen mode Exit fullscreen mode

Alternatives

I'm assuming that your project is already importing a library to perform HTTP request. And this is exactly what we will try to reuse.

1. Axios

If your project is already using axios this snippet is for you:

describe('[AXIOS] Http server Testing', () => {
  test('POST /users (201)', async () => {
    const server = app.listen(0)
    const { port } = server.address()
    const instance = axios.create({
      baseURL: `http://127.0.0.1:${port}`,
      responseType: 'json'
    })
    const response = await instance.post('users', {  name: 'Joe' })
    server.close()
    expect(response.status).toBe(201)
    const expectedBody = {
      id: 1,
      name: 'Joe'
    }
    expect(response.data).toEqual(expectedBody)
  })
})
Enter fullscreen mode Exit fullscreen mode

2. GOT

If your project is already using GOT this snippet is for you:

describe('[GOT] Http server Testing', () => {
  test('POST /users (201)', async () => {
    const server = app.listen(0)
    const { port } = server.address()
    const instance = got.extend({
      prefixUrl: `http://127.0.0.1:${port}`,
      responseType: 'json'
    })
    const response = await instance.post('users', {
      json: { 
        name: 'Joe'
      }
    })
    server.close()
    expect(response.statusCode).toBe(201)
    const expectedBody = {
      id: 1,
      name: 'Joe'
    }
    expect(response.body).toEqual(expectedBody)
  })
})
Enter fullscreen mode Exit fullscreen mode

3. Node Fetch

If your project is already using node fetch this snippet is for you:

describe('[FETCH] Http server Testing', () => {
  test('POST /users (201)', async () => {
    const server = app.listen(0)
    const { port } = server.address()
    const response = await fetch(`http://127.0.0.1:${port}/users`, {
      method: 'post',
      body: JSON.stringify({ name: 'Joe' }),
      headers: {'Content-Type': 'application/json'}
    });
    server.close()
    expect(response.status).toBe(201)
    const expectedBody = {
      id: 1,
      name: 'Joe'
    }
    expect(response.json()).resolves.toEqual(expectedBody)
  })
})
Enter fullscreen mode Exit fullscreen mode

I hope you like it and understand how you can easily improve the long term maintenance of your project.
Let me know which flavor you like, I will share a more snippet soon.

You can find the full detail of the implementation here: https://github.com/olivierodo/nodejs-packageless/tree/main/supertest

Feel free to contribute if you know another way to reduce the dependency with supertest 😇.

Top comments (0)