10

Both Axios and Supertest can send HTTP requests to a server. But why is Supertest used for testing while Axios is used for practice API calls?

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
6991httam
  • 305
  • 4
  • 14
  • Super*test* is used for testing because it adds a test API, are you asking about the comparison between Axios and Super*agent*? – jonrsharpe Jul 20 '20 at 08:32
  • No it's right. It's about Supertest. I don't know why people use supertest to test their http server while axios can send http request – 6991httam Jul 20 '20 at 08:48
  • 1
    Because Supertest can *"provide a high-level abstraction for testing HTTP"*; you *could* test using Axios, or anything else that can send a request (like Superagent directly), but then you'd have to write all of the assertions yourself. – jonrsharpe Jul 20 '20 at 08:49
  • Ah, that's why most of people use `Jest` with `Supertest`. Thank you. But I think I've seen that there is also requesting function in `Jest` itself. isn't it? I mean `jest.fn()` – 6991httam Jul 20 '20 at 08:52
  • No, [`jest.fn()`](https://jestjs.io/docs/en/jest-object#jestfnimplementation) doesn't make requests, it creates a mock function. And you can use Supertest (or Axios, Superagent, ...) with any test runner/framework. – jonrsharpe Jul 20 '20 at 08:53
  • 1
    Also with a vanilla request library you'd also have to start the app yourself, because you wouldn't have `request(app)` to do that any more. – jonrsharpe Jul 20 '20 at 08:56
  • I think I get it a bit more! Thank you very much!! – 6991httam Jul 21 '20 at 10:08

2 Answers2

23

There are two reasons to use Supertest rather than a vanilla request library like Axios (or Superagent, which Supertest wraps):

  1. It manages starting and binding the app for you, making it available to receive the requests:

    You may pass an http.Server, or a Function to request() - if the server is not already listening for connections then it is bound to an ephemeral port for you so there is no need to keep track of ports.

    Without this, you'd have to start the app and set the port yourself.

  2. It adds the expect method, which allows you to make a lot of common assertions on the response without having to write it out yourself. For example, rather than:

    // manage starting the app somehow...
    
    axios(whereAppIs + "/endpoint")
      .then((res) => {
        expect(res.statusCode).toBe(200);
      });
    

    you can write:

    request(app)
      .get("/endpoint")
      .expect(200);
    
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
  • 1
    Wow, this shows what I exactly want to know! Perfect comparison, Thank you! – 6991httam Jul 21 '20 at 10:29
  • 2
    I see the first example of axios much cleaner and more understandable. when you say in English "I expect the response status to be 200" its much cleaner than you say "I expect 200" so what is 200 meant to be? – Anas Nov 28 '21 at 13:34
  • 1
    @Anas then use that version, supertest isn't mandatory. Note you can also do e.g. `.then(({ status }) => { expect(status).toBe(200); })` _with supertest_ if you want to. You could also have an alias like `HttpStatus.OK`, rather than the magic number, in any version. – jonrsharpe Nov 28 '21 at 13:37
  • Thanks for the info but isn’t it also possible to just do: const response = await axios();jest.expect(response).toBe(ok) – Abduladil Sunnat Jun 01 '23 at 10:31
  • @AbduladilSunnat something like that, yes; again it's not mandatory. – jonrsharpe Jun 01 '23 at 17:21
2

Because Supertest provide some assertions API that axios not provide. So people usually using Supertest to doing http assertion testing.

e.g.

const request = require('supertest');

describe('GET /user', function() {
 it('responds with json', function(done) {
   request(app)
     .get('/user')
     .auth('username', 'password')
     .set('Accept', 'application/json')
     .expect('Content-Type', /json/)
     .expect(200, done);
 });
});
Eason
  • 469
  • 4
  • 14