Giter VIP home page Giter VIP logo

Comments (5)

developit avatar developit commented on May 18, 2024 1

How are you running multiple tests? If you're getting address in use issues that would seem like you're re-initializing the server on each test without cleanly shutting it down.

You might have better luck disabling the HTTP server and just using your server as an Express middleware. Just set an env var in your tests like NODE_ENV=test and change your src/index.js to something like this:

import http from 'http';
import express from 'express';
import cors from 'cors';
import morgan from 'morgan';
import bodyParser from 'body-parser';
import initializeDb from './db';
import middleware from './middleware';
import api from './api';
import config from './config.json';

let app = express();
+if (process.env.NODE_ENV!=='test') {
	app.server = http.createServer(app);
+}

// logger
app.use(morgan('dev'));

// 3rd party middleware
app.use(cors({
	exposedHeaders: config.corsHeaders
}));

app.use(bodyParser.json({
	limit : config.bodyLimit
}));

// connect to db
initializeDb( db => {

	// internal middleware
	app.use(middleware({ config, db }));

	// api router
	app.use('/api', api({ config, db }));

+	if (app.server) {
		app.server.listen(process.env.PORT || config.port);
+	}

	console.log(`Started on port ${app.server.address().port}`);
});

export default app;

from express-es6-rest-api.

SpencerCDixon avatar SpencerCDixon commented on May 18, 2024

First, thank you for the very detailed and thoughtful response!

I must have been starting it up twice because I was just importing the index.js file as 'app' and passing that to supertest.

Making your changes fixed the problem! Unfortunately, now the server just hangs after all the tests are run. Not entirely sure why that would be. I've tired putting like a global afterAll() hook to close it but no luck. For reference:

index.js

import http from "http";
import express from "express";
import cors from "cors";
import morgan from "morgan";
import bodyParser from "body-parser";
import initializeDb from "./db";
import middleware from "./middleware";
import api from "./api";
import config from "./config.js";
import expressJwt from "express-jwt";

let app = express();

if (!config.isTest()) {
  app.server = http.createServer(app);
}

// --------------------------
// Dev Middleware
// --------------------------
if (config.isDev()) {
  app.use(morgan("dev"));
}

// --------------------------
// 3rd party middleware
// --------------------------
app.use(
  cors({
    exposedHeaders: config.corsHeaders
  })
);

app.use(
  bodyParser.json({
    limit: config.bodyLimit
  })
);

app.use(
  expressJwt({
    secret: config.jwtSecret
  }).unless({
    path: ["/api", "/api/accounts", "/api/authenticate"]
  })
);

// --------------------------
// Connect to DB and start app
// --------------------------
initializeDb(db => {
  // internal middleware
  app.use(middleware({ config, db }));

  // -----------------
  // Set up API routes
  // -----------------
  app.use("/api", api({ config, db }));

  // ---------------------
  // Listen to server port
  // ---------------------
  if (app.server) {
    app.server.listen(process.env.PORT || config.port);
    console.log(`Started on port ${app.server.address().port}`);
  }
});

export default app;

Test file:

import request from 'supertest';
import app from '../../index.js';

// Tried this but doesn't work.
// afterAll(function(done) {
  // app.server.close(done)
// });

describe('accounts', function() {
  describe('POST /accounts', function() {
    it('lets you create a new account', function() {
      return request(app)
        .post('/api/accounts')
        .send({
          email: '[email protected]',
          password: 'examplepass',
          created_at: Date.now(),
          updated_at: Date.now(),
        })
        .expect(201)
        .expect(({body}) => {
          expect(body.account.email).toEqual('[email protected]')
        });
    });
  });
});

Appreciate any advice you can give. Feel like I might be missing something obvious here haha.

from express-es6-rest-api.

developit avatar developit commented on May 18, 2024

Hmm - definitely a supertest thing.. what about calling .end?

describe('accounts', function() {
  describe('POST /accounts', function() {
    it('lets you create a new account', function() {
      return request(app)
        .post('/api/accounts')
        .send({
          email: '[email protected]',
          password: 'examplepass',
          created_at: Date.now(),
          updated_at: Date.now(),
        })
        .expect(201)
        .expect(({body}) => {
          expect(body.account.email).toEqual('[email protected]')
        })
        .end();
    });
  });
});

from express-es6-rest-api.

SpencerCDixon avatar SpencerCDixon commented on May 18, 2024

I figured it out!

So it turns out it was because I still had a DB handle active and node will hang whenever there are handles open. This was the code to fix:

afterAll(function(done) {
  app.server.close(done)
});

afterAll(function(done) {
  knex.destroy(done);
});

Seems a little silly that I have to add these in order to write pretty standard API tests. There must be a better way than I'm approaching it but at least I can continue onwards. Thanks @developit 👍

EDIT:
I actually JUST needed to kill the knex handles. So just this fixes it:

afterAll(function(done) {
  knex.destroy(done);
});

(Using Jest in 'node' mode and supertest for any future folks looking at this)

from express-es6-rest-api.

developit avatar developit commented on May 18, 2024

Nice! I had wondered about that - was going to suggest hooking app.server.on('close'), but I think it's attached as app._server under supertest.

from express-es6-rest-api.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.