1

I have an express POST route set-up in index.js as following

  import * as Busboy from 'busboy';
  public publish = async (req: Request, res: Response) => {
    const busboy = new Busboy({ headers: req.headers });
    const pl = { title: '' };
    busboy.on('field', (fieldname, val) => {
      switch (fieldname) {
        case 'title':
          pl.title = val;
          break;
      }
    });
    busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
      // Process files
    });
    busboy.on('finish', async () => {
      // Process request
      res.send({payload: pl});
    });
  } 

In test index.test.js using jest how do i mock this module in such a way that i can validate the response containing the form field title sent in request?

Currently i use jest.mock('busboy'); but nothing gets invoked due to this.

jest.mock('busboy');
let service: ServiceController;
describe('Mosaic Research Capture Service', () => {
  it('should publish', async () => {
    service = new ServiceController();
    const req = {
      headers: {
        'Content-Type': 'multipart/form-data'
      },
      body: {}
    };
    const res = {
      send: jest.fn()
    };
    await service.publish(req, res);
  });
});

The React client invokes this request as follows

 const formData = new FormData();
 formData.append('title', 'SomeTitle');
 const header = {
   credentials: 'include',
   'Content-Type': 'multipart/form-data',
 };
 const response =  await axios.post('/publish, formData, header); 
Lin Du
  • 88,126
  • 95
  • 281
  • 483
meteor
  • 2,518
  • 4
  • 38
  • 52

1 Answers1

0

You need a "trick" to mock a event-listener action. As a issue https://github.com/airbnb/enzyme/issues/426

You abuse async/await many times, just use these keywords if you working with Promises.

Here is my suggest update for your case:

index.js : Just remove all async keywords

 import * as Busboy from 'busboy';
  public publish = (req: Request, res: Response) => {
    const busboy = new Busboy({ headers: req.headers });
    const pl = { title: '' };
    busboy.on('field', (fieldname, val) => {
      switch (fieldname) {
        case 'title':
          pl.title = val;
          break;
      }
    });
    busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
      // Process files
    });
    busboy.on('finish', () => {
      // Process request
      res.send({payload: pl});
    });
  } 

index.test.js

import { ServiceController } from "./handler";
import * as Busboy from 'busboy';

jest.mock('busboy');
describe('Mosaic Research Capture Service', () => {
  let service: ServiceController;
  const mockedEvenMap = {};

  beforeAll(() => {
    Busboy.mockImplementation(() => {
      return { // mock `on` event of Busby instance
        on: (event, callback) => {
          mockedEvenMap[event] = callback;
        },
      };
    });

    service = new ServiceController();
  });

  afterAll(() => {
    Busboy.mockRestore();
  });

  it('should publish', () => {
    const expectedTile = "MY_TITLE";
    const filenameToTest = 'title';

    const req = {
      headers: {
        'Content-Type': 'multipart/form-data'
      },
      body: {}
    };
    const res = {
      send: jest.fn()
    };
    service.publish(req, res); // remove await

    // fire simulate event
    mockedEvenMap['field'](filenameToTest, expectedTile);
    mockedEvenMap['finish']();

    // you expect send function will be call with a payload with includes the title
    expect(res.send).toBeCalledWith({ payload: {title: expectedTile} });
  });
});

hoangdv
  • 15,138
  • 4
  • 27
  • 48