Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to start an express server using testEnvironment as NodeEnvironment?

After looking into the questions:

  1. Async setup of environment with Jest
  2. window/document not defined in import
  3. Configure Jest global tests setup with .ts file (TypeScript)
  4. About app.listen() callback
  5. How to write a Jest configuration file
  6. NodeJS: How to get the server's port?
  7. https://alligator.io/nodejs/serving-static-files-in-express/
  8. Promisify server.listen
  9. Unexpected token import in custom node environment
  10. How to access class properties of Jest Test Environment inside child test?
  11. Cannot create custom TestEnvironment in Jest
  12. globalSetup is executed in different context than tests
  13. global beforeAll
  14. How to test url change with Jest
  15. Specify window.location for each test file for Jest
  16. window.location.href can't be changed in tests
  17. global beforeAll
  18. How do I test a single file using Jest?
  19. https://basarat.gitbook.io/typescript/intro-1/jest

I was able to do this:

package.json

{
  "name": "my-project",
  "jest": {
    "testEnvironment": "./testEnvironment.js",
  }
}

testEnvironment.js

const express = require('express');
// const NodeEnvironment = require('jest-environment-node'); // for server node apps
const NodeEnvironment = require('jest-environment-jsdom'); // for browser js apps

class ExpressEnvironment extends NodeEnvironment {
  constructor(config, context) {
    super(config, context);
  }

  async setup() {
    await super.setup();
    const app = express();

    this.global.server = app.listen(0, "127.0.0.1", () => {
        console.log(`Running express server on '${JSON.stringify(server.address())}'...`);

        how to make setup() wait until app.listen callback is finished, 
        i.e., the server has properly started.

    });
    app.use(express.static('../testfiles'));
  }

  async teardown() {
    this.global.server.close();
    await super.teardown();
  }

  runScript(script) {
    return super.runScript(script);
  }
}

module.exports = ExpressEnvironment;

How to make setup() wait until app.listen() callback is finished, i.e., the server has properly started?

Before, when I was using beforeAll(), my code was working fine because I could use the done() async callback passed by beforeAll():

const express = require('express');
const app = express();
var server;

beforeAll(async (done) => {
    server = app.listen(0, "127.0.0.1", () => {
        console.log(`Running express server on '${JSON.stringify(server.address())}'...`);
        done();
    });
    app.use(express.static('../testfiles'));
});

afterAll(() => {
    server.close();
});

How would be the equivalent to the beforeAll done() callback on the NodeEnvironment setup() function?

like image 992
user Avatar asked Nov 18 '25 09:11

user


1 Answers

You can do this by awaiting the listen even, wrapping it in a promise, and calling the promise resolve as the callback to the server listen

  const app = express();
  let server;
  await new Promise(resolve => server = app.listen(0, "127.0.0.1", resolve));
  this.global.server = server;

You could also put a custom callback that will just call the promise resolver as the third argument to the app.listen() and it should run that code then call resolve if you need some sort of diagnostics.

like image 68
Robert Mennell Avatar answered Nov 20 '25 23:11

Robert Mennell



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!