使用玩笑测试具有异步函数侦听器的 eventEmitter

Testing eventEmitter which has an async function listener using jest

我定义了一个 async 函数,其中包含 await 语句,并将其用作 pubsub 订阅消息的侦听器。想用玩笑来测试这个。但是遇到了问题。

代码:


const pubsubPull = () => {
  const pubsub = new PubSub();
  const subscription = pubsub.subscription("test-sub");
  const handler = async message => {
    try {
      const payload = Buffer.from(message.data, "base64").toString();
      const data = JSON.parse(payload).data;
      await repository.insert(data);
      message.ack();
    } catch (err) {
      console.log("error")
    }
  };
  subscription.on("message", handler);
};

测试:

jest.mock("@google-cloud/pubsub");
jest.mock("./repository");

describe("listener", () => {
  const data = {
    id: "3ce91594-f648-41bf-9a37-4fa09c4afb3b",
    name: "ABCD",
    value: 1234
  };
  const eventBuffer = Buffer.from(JSON.stringify(data));
  const message = {
    id: "1561624788277",
    data: eventBuffer,
    ack: jest.fn()
  };

  const mockSubscripton = new EventEmitter();
  const pubsubClient = {
    subscription: jest.fn().mockReturnValue(mockSubscripton)
  };

  beforeAll(() => {
    PubSub.mockImplementation(() => pubsubClient);
    repository.insert.mockResolvedValue(true);
  });

  it("should ack the message", (done) => {
    pubsubPull();
    mockSubscripton.emit("message", message);

    expect(message.ack).toHaveBeenCalled();
    done();
  });
});

测试失败 Expected mock function to have been called. But it was not called. 这意味着断言甚至在侦听器函数执行完成之前就已完成。 我如何才能等待它完成并 运行 断言。 任何帮助表示赞赏。 节点 v10.11.0,开玩笑“24.8.0”

一个天真但简单的解决方案是使用 setTimeout 进行断言,给异步订阅者足够的时间来执行。

it("should ack the message", done => {
  pubsubPull();
  mockSubscripton.emit("message", message);

  setTimeout(() => {
    expect(message.ack).toHaveBeenCalled();
    done();
  }, 100);
});