【问题标题】:jest: how to mock a dependency that listens to events?笑话:如何模拟监听事件的依赖项?
【发布时间】:2019-06-14 18:33:01
【问题描述】:

我遇到了一个非常复杂的情况。 我会尽量保持简洁。

所以我在 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 };

我可以模拟一些东西,例如:createClient。 我无法模拟的是事件部分我什至不知道该怎么做。还有.as().post() 部分。

这是我的开玩笑测试的样子:

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();
    }
  })
});

任何帮助,非常感谢。

我试图找到类似的问题,但在这一点上,我的大脑刚刚停止工作...... 如果您需要更多详细信息,请告诉我。

【问题讨论】:

  • 如果我错了,请纠正我,您是否需要使用 post 回调返回数据来模拟 success 事件。我做对了吗?
  • 在某种程度上,是的。我还想模拟错误事件。但是,如果您给我成功的解决方案,我会从中弄清楚。

标签: javascript node.js ecmascript-6 jestjs es6-promise


【解决方案1】:

这是你需要做的:

// 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;
});

这只是您需要放入 test.js 文件中的模拟对象。

不确定此代码是否可以按原样运行,尽管不需要大量调试。

如果您只是想要积极的情况,请删除第二个 mockImplementationOnce 并将第一个 mockImplementationOnce 替换为 mockImplementation

【讨论】:

  • 我不得不根据我的逻辑进行一些更改。虽然答案对我很有效。
猜你喜欢
  • 2019-08-08
  • 1970-01-01
  • 1970-01-01
  • 2021-05-22
  • 1970-01-01
  • 1970-01-01
  • 2021-02-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多