7

I tried to set up jest, supertest, and express but failed. I have these 2 simple file

index.js

const express = require("express");
const app = express();
const port = 3000;

app.get("/", (req, res) => res.send("Hello World!"));

app.listen(port, () => console.log(`Example app listening on port ${port}!`));

and index.test.js

const express = require("express");
const app = express();
const request = require("supertest");

describe("/", () => {
  test("it says hello world", done => {
    request(app)
      .get("/")
      .expect(200)
      .end(function(err, res) {
        console.log("err", err);
      });
  });
});

when I run the test I'm getting this error. err Error: expected 200 "OK", got 404 "Not Found"

What's wrong?

I visit localhost:3000 in my browser I can see 'Hello World!'

Yilmaz
  • 35,338
  • 10
  • 157
  • 202
Hanz
  • 499
  • 7
  • 18
  • The issue is with the new app instance in test file. You should export app instance from index.js and use it in index.test.js or write the tests along with code in index.js which is not preferred for production code. – PrivateOmega May 14 '19 at 04:13
  • I got this error now ` listen EADDRINUSE: address already in use :::3000` – Hanz May 14 '19 at 04:19
  • Don't start the server using `node index.js` or something similiar. Supertest would run it. "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." – PrivateOmega May 14 '19 at 04:22
  • Refer to a [tutorial](https://hackernoon.com/api-testing-using-supertest-1f830ce838f1) which would explain steps in detail. I gave a quick look, didn't read the entire thing though. – PrivateOmega May 14 '19 at 04:25

2 Answers2

6

you should refactor index.js and create app.js

app.js

const express = require("express");
const app = express();
app.get("/", (req, res) => res.send("Hello World!"));

index.js

const app = require('./app')
const port = process.env.PORT
app.listen(port, () => { console.log(`listening on ${port}) . })

the reason why we restructure the code like this is we need to access to express app() but we do not want "listen" to be called.

in your test file

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

describe("/", () => {
  test("it says hello world", done => {
    request(app)
      .get("/")
      .expect(200)
      .end(function(err, res) {
        console.log("err", err);
      });
  });
});
Yilmaz
  • 35,338
  • 10
  • 157
  • 202
0

It's because app instance in your test is different from the one running in your index.js

Export app from your index.js:

const server = app.listen(port, () => console.log(`Example app listening on port ${port}!`));
module.exports = server;

And import in your test:

const server = require('./index.js');

// pass your server to test
...
request(server)
  .get("/")
...
1565986223
  • 6,420
  • 2
  • 20
  • 33