最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Start and stop server with supertest - Stack Overflow

programmeradmin5浏览0评论

I have the following server class :

import express, { Request, Response } from 'express';

export default class Server {
  server: any;

  exp: any;

  constructor() {
    this.exp = express();
    this.exp.get('/', (_req: Request, res: Response) => {
      res.json('works');
    });
  }

  start(): void {
    this.server = this.exp.listen(3000);
  }

  stop(): void {
    this.server.close();
  }
}

I'm using supertest for end-to-end testing. I wish to start my application beforeAll tests and stop it when the tests are done.

It's easy to do that using beforAll and afterAll where I can just once instanciate the Server class and call the start and close methods.

But as I have 10+ controllers to test, I want to avoid to start and stop the server during each test file.

I found on the documentation the setupFiles and setupFilesAfterEnv but I can't stop the server since the instance is not "shared" in the two files.

This is an example of 1 test file :

import supertest from 'supertest';

describe('Album Test', () => {
   let app: App;

   beforeAll(async (done) => {
     app = new App();

     await app.setUp(); // database connection (not mentionned in the preivous example)
     done();
   });

   afterAll(async (done) => {
     await app.close();

     app.server.stop();
     done();
   });

  const api = supertest('http://localhost:3000');

  it('Hello API Request', async () => {
    const result = await api.get('/v1/user');
    expect(result.status).toEqual(200);
    ...
  });
});

This works totally fine but I'm duplicating this beforeAll and afterAll methods in every test file. Is there a way to declare it only once ?

Thanks

I have the following server class :

import express, { Request, Response } from 'express';

export default class Server {
  server: any;

  exp: any;

  constructor() {
    this.exp = express();
    this.exp.get('/', (_req: Request, res: Response) => {
      res.json('works');
    });
  }

  start(): void {
    this.server = this.exp.listen(3000);
  }

  stop(): void {
    this.server.close();
  }
}

I'm using supertest for end-to-end testing. I wish to start my application beforeAll tests and stop it when the tests are done.

It's easy to do that using beforAll and afterAll where I can just once instanciate the Server class and call the start and close methods.

But as I have 10+ controllers to test, I want to avoid to start and stop the server during each test file.

I found on the documentation the setupFiles and setupFilesAfterEnv but I can't stop the server since the instance is not "shared" in the two files.

This is an example of 1 test file :

import supertest from 'supertest';

describe('Album Test', () => {
   let app: App;

   beforeAll(async (done) => {
     app = new App();

     await app.setUp(); // database connection (not mentionned in the preivous example)
     done();
   });

   afterAll(async (done) => {
     await app.close();

     app.server.stop();
     done();
   });

  const api = supertest('http://localhost:3000');

  it('Hello API Request', async () => {
    const result = await api.get('/v1/user');
    expect(result.status).toEqual(200);
    ...
  });
});

This works totally fine but I'm duplicating this beforeAll and afterAll methods in every test file. Is there a way to declare it only once ?

Thanks

Share Improve this question edited May 11, 2020 at 8:20 Lin Du 103k136 gold badges334 silver badges565 bronze badges asked May 7, 2020 at 14:10 TLdTLd 6522 gold badges9 silver badges25 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 3

Try this it works

const supertest = require('supertest')
const app = require('../../app')

describe('int::app', function(){

  let request = null
  let server = null

  before(function(done){
    server = app.listen(done)
    request = supertest.agent(server)
  })

  after(function(done){
    server.close(done)
  })

  it('should get /api/v1/laps/85299', function(){
    return request.get('/api/v1/laps/85299')
      .expect(200, { data: {} })
  })

})

You could use setupFiles to set up test fixtures globally. You can assign variables that you want to use in multiple test files to Node.js global object.

E.g.

app.ts:

import express, { Request, Response } from 'express';

export default class Server {
  server: any;

  exp: any;

  constructor() {
    this.exp = express();
    this.exp.get('/', (_req: Request, res: Response) => {
      res.json('works');
    });
  }

  start(): void {
    this.server = this.exp.listen(3000);
  }

  stop(): void {
    this.server.close();
  }
}

app.setup.js:

const App = require('./app').default;

beforeAll(() => {
  global.app = new App();
  global.app.exp.set('test setup', 1);
  console.log('app setup');
});

afterAll(() => {
  console.log('app stop');
});

jest.config.js:

module.exports = {
  preset: 'ts-jest/presets/js-with-ts',
  testEnvironment: 'node',
  setupFilesAfterEnv: [
    './jest.setup.js',
    '/Users/ldu020/workspace/github./mrdulin/react-apollo-graphql-starter-kit/stackoverflow/61659975/app.setup.js',
  ],
  testMatch: ['**/?(*.)+(spec|test).[jt]s?(x)'],
  verbose: true,
};

a.controller.test.js:

describe('controller a', () => {
  it('should pass', () => {
    console.log('test setup:', global.app.exp.get('test setup'));
    expect(1 + 1).toBe(2);
  });
});

b.controller.test.js:

describe('controller b', () => {
  it('should pass', () => {
    console.log('test setup:', global.app.exp.get('test setup'));
    expect(1 + 1).toBe(2);
  });
});

unit test results:

 PASS  stackoverflow/61659975/a.controller.test.js
  controller a
    ✓ should pass (5ms)

  console.log
    app setup

      at Object.<anonymous> (stackoverflow/61659975/app.setup.js:6:11)

  console.log
    app setup

      at Object.<anonymous> (stackoverflow/61659975/app.setup.js:6:11)

  console.log
    test setup: 1

      at Object.<anonymous> (stackoverflow/61659975/b.controller.test.js:3:13)

  console.log
    test setup: 1

      at Object.<anonymous> (stackoverflow/61659975/a.controller.test.js:3:13)

  console.log
    app stop

      at Object.<anonymous> (stackoverflow/61659975/app.setup.js:10:11)

  console.log
    app stop

      at Object.<anonymous> (stackoverflow/61659975/app.setup.js:10:11)

 PASS  stackoverflow/61659975/b.controller.test.js
  controller b
    ✓ should pass (3ms)

Test Suites: 2 passed, 2 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        6.749s, estimated 12s
发布评论

评论列表(0)

  1. 暂无评论