admin管理员组

文章数量:1388853

I came across a very plicated situation. I'll try to keep it as concise as possible.

So I have a code like this in myModule.js:

const lib = require('@third-party/lib');

const myFunction = () => {
  const client = lib.createClient('foo');
  return new Promise((resolve, reject) => {
    client.on('error', (err) => reject(err));
    client.on('success', () => {
      client.as(param1).post(param2, param3, (err, data) => {
        if (err) reject(err);

        // Some important logical processing of data
        resolve(data);
      });
    });
  });
}

module.exports = { myFunction };

There are a few things I am able to mock, like: createClient. What I am not able to mock is the event part I don't even know how to do this. And the .as().post() part.

Here's how my jest test looks like:

const myModule = require('./myModule');
const mockData = require('./mockData');

describe('myFunction', () => {

  it('Should resolve promise when lib calls success event', async () => {
    try {
      const myData = await myModule.myFunction();
      expect(myData).toMatchObject(mockData.resolvedData);
    } catch (err) {
      expect(err).toBeNull();
    }
  })
});

Any help, much Appreciated.

I tried to find similar questions but at this point, my mind has just stopped working... Please let me know if you need any more details.

I came across a very plicated situation. I'll try to keep it as concise as possible.

So I have a code like this in myModule.js:

const lib = require('@third-party/lib');

const myFunction = () => {
  const client = lib.createClient('foo');
  return new Promise((resolve, reject) => {
    client.on('error', (err) => reject(err));
    client.on('success', () => {
      client.as(param1).post(param2, param3, (err, data) => {
        if (err) reject(err);

        // Some important logical processing of data
        resolve(data);
      });
    });
  });
}

module.exports = { myFunction };

There are a few things I am able to mock, like: createClient. What I am not able to mock is the event part I don't even know how to do this. And the .as().post() part.

Here's how my jest test looks like:

const myModule = require('./myModule');
const mockData = require('./mockData');

describe('myFunction', () => {

  it('Should resolve promise when lib calls success event', async () => {
    try {
      const myData = await myModule.myFunction();
      expect(myData).toMatchObject(mockData.resolvedData);
    } catch (err) {
      expect(err).toBeNull();
    }
  })
});

Any help, much Appreciated.

I tried to find similar questions but at this point, my mind has just stopped working... Please let me know if you need any more details.

Share Improve this question edited Jan 21, 2019 at 11:37 giampaolo 6,9345 gold badges46 silver badges75 bronze badges asked Jan 21, 2019 at 11:14 Vijay GaikwadVijay Gaikwad 4671 gold badge5 silver badges16 bronze badges 2
  • 2 Correct me if I'm wrong, do you need to mock success event with a post callback returning data. Do I get this right? – darth-coder Commented Jan 21, 2019 at 11:17
  • In a way, YES. I also want to mock the error event. But if you give me the solution to success I will figure it out from that. – Vijay Gaikwad Commented Jan 21, 2019 at 11:20
Add a ment  | 

1 Answer 1

Reset to default 4

Here’s what you need to do:

// EventEmitter is here to rescue you
const events = require("events");

// Mock the third party library
const lib = require("@third-party/lib");

lib.createClient.mockImplementationOnce(params => {
  const self = new events.EventEmitter();

  self.as = jest.fn().mockImplementation(() => {
    // Since we're calling post on the same object.
    return self;
  });

  self.post = jest.fn().mockImplementation((arg1, _cb) => {
    // Can have a conditional check for arg 1 if so desird
    _cb(null, { data : "foo" });
  });

  // Finally call the required event with delay.
  // Don't know if the delay is necessary or not.
  setInterval(() => {
    self.emit("success");
  }, 10);
  return self;
}).mockImplementationOnce(params => {
  const self = new events.EventEmitter();

  // Can also simulate event based error like so:
  setInterval(() => {
    self.emit("error", {message: "something went wrong."});
  }, 10);
  return self;
}).mockImplementationOnce(params => {
  const self = new events.EventEmitter();
  self.as = jest.fn().mockImplementation(() => {
    return self;
  });

  self.post = jest.fn().mockImplementation((arg1, _cb) => {
    // for negative callback in post I did:
    _cb({mesage: "Something went wrong"}, null);
  });

  setInterval(() => {
    self.emit("success");
  }, 10);
  return self;
});

This is only the mock object that you need to put in your test.js file.

Not sure if this code will work as is, although won’t require a lot of debugging.

If you just want to positive scenario, remove the second mockImplementationOnce and replace the first mockImplementationOnce with just mockImplementation.

本文标签: javascriptjest how to mock a dependency that listens to eventsStack Overflow