29. Testing server response

The question now is how can we test our Express instance. Well, there's a library designed exactly for this called Supertest.

In fact, this library was created by the developers who created Express and is therefore perfect for the job.

Let's install that by going:

$ npm i -D supertest@3

To use Supertest, let's first require it at the top of the file. The idiosyncratice way of using it is to assign the Supertest module to a constant called request:

tests/item.test.js

const app = require("../../../server");
const expect = require("expect");
const request = require("supertest");

Setting up request

We're now going to write a test for our POST /items endpoint. In it, we want to ensure a new model is written to the database if the correct data is supplied.

Let's use Supertest by calling request and passing in the Express server. Now all we need to do is is use the relevant HTTP verb as a method, so in this case, post.

To that method we pass the URL we want to make this request to, in this case, /items.

Note that we'll also need to await this method.

tests/item.test.js

describe("POST /items", () => {
  it("should create a new item", async () => {
    await request(app)
      .post("/items")
  });
});

Body

Our POST request requires data to be sent along with it, of course. So let's define the body data in an object before we make the request. So we'll go const body = { title: "Test title" };

We'll then chain another method send and pass in that body object.

tests/item.test.js

const body = { title: "Test title" };
await request(app)
  .post("/items")
  .send(body)

HTTP assertion

Obviously our unit test requires us to make an assertion. To do this, we'll chain another method to the request which is expect.

Now, it's important to note taht this is a Supertest method, so don't confuse this with the expect assertion library; they just happen to share the same name!

expect is a versatile method that can take several different arguments types. In our case, we're going to pass in an HTTP status code, 200 in the case.

Response assertion

Next, we want to make an assertion about the response of the server call.

Let's assign the output of the promise to a variable res.

Now, we can use the expect library again, and expect the body to include the item title. To do this, we'll expect res.body.item.title, to be body.title.

With that assertion made, we can be pretty sure our endpoint is responding how we'd exepct.

tests/item.test.js

const body = { title: "Test title" };
const res = await request(app)
  .post("/items")
  .send(body)
  .expect(200);
expect(res.body.item.title).toBe(body.title);

Let's run that and see what we get. Bingo, it works.

Discussion

0 comments