Home > Blockchain >  Jest: How to avoid boilerplate in beforeEach / afterEach
Jest: How to avoid boilerplate in beforeEach / afterEach

Time:01-19

I have multiple service tests that have almost equal beforeEach() and afterAll(). What can be done to eliminate the boilerplate?

It looks simplified like this:

describe('Test',()=>{
  let serverTestbed:ServerTestbed;
  let myService:MyService;
  beforeEach(()=>{
    serverTestbed= new ServerTestbed()
    serverTestbed.run()

    myService= new MyService(serverTestbed.host,serverTestbed.port) 
    //^^ this is the only line that differs from test to test
  })

  afterEach(async ()=>{
    await serverTestbed.close()

  })
})

Is it possible to do something like this, where describeServerTest(..) contains the duplicate actions:

describeServerTest("test my service",(serverTestbed)=>{
  let myService:MyService
  //more varibales here

  beforeEach(()=>{
   myService= new MyService(serverTestbed.host,serverTestbed.port) 
   //other init stuff
  })

  it('test',()=>{
    myService.foo()
    expect(..)
  })
})

CodePudding user response:

I assume you want to import the describeServerTest function in each test file rather than a global setup using setupFilesAfterEnv config.

From the documentation Defining Tests , we know:

Tests must be defined synchronously for Jest to be able to collect your tests.

E.g.

test-utils.ts:

const serverTestbed = {
  host: '127.0.0.1',
  port: 5432,
};
type EmptyFunction = () => void;
interface FunctionLike {
  readonly name: string;
}
export const describeServerTest = (name: number | string | Function | FunctionLike, fn: EmptyFunction): void => {
  describe(name, () => {
    beforeEach(() => {
      console.log('server testbed run');
    });

    afterEach(async () => {
      console.log('server testbed close');
    });

    fn();
  });
};

a.test.ts:

import { describeServerTest } from './test-utils';

describeServerTest('test a service', () => {
  it('should pass', () => {
    console.log('a service test case run');
    expect(1   1).toEqual(2);
  });
});

b.test.ts:

import { describeServerTest } from './test-utils';

describeServerTest('test b service', () => {
  it('should pass', () => {
    console.log('b service test case run');
    expect(1   1).toEqual(2);
  });
});

Test result:

 PASS  stackoverflow/75135319/b.test.ts (8.032 s)
  ● Console

    console.log
      server testbed run

      at Object.<anonymous> (stackoverflow/75135319/test-utils.ts:12:15)

    console.log
      b service test case run

      at Object.<anonymous> (stackoverflow/75135319/b.test.ts:5:13)

    console.log
      server testbed close

      at stackoverflow/75135319/test-utils.ts:16:15

 PASS  stackoverflow/75135319/a.test.ts (8.048 s)
  ● Console

    console.log
      server testbed run

      at Object.<anonymous> (stackoverflow/75135319/test-utils.ts:12:15)

    console.log
      a service test case run

      at Object.<anonymous> (stackoverflow/75135319/a.test.ts:5:13)

    console.log
      server testbed close

      at stackoverflow/75135319/test-utils.ts:16:15


Test Suites: 2 passed, 2 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        8.997 s, estimated 10 s
Ran all test suites related to changed files.
  • Related