javascript 如何测试作为参数传递的函数是否在Jest中被调用

fslejnso  于 2023-01-01  发布在  Java
关注(0)|答案(1)|浏览(155)

我有一个函数接收另一个函数作为参数。我希望确保它被正确调用。
待测功能:

const loadNamespaces = (setNamespaces) => {
  namespaceAPI.getNamespaces().then(namespaces => {
    setNamespaces(namespaces);
  });
}

我在这里的主要目标是AssertmockSetNamespaces被调用了。
我可以使用jest.spyOn方法模拟和AssertnamespaceAPI.getNamespaces被调用,但如果mockSetNamespaces被调用,则无法Assert:

test("loadNamespaces", () => {
  const mockSetNamespaces = jest.fn();

  const mockNamespaces = [
    { endpoint: "mock namespace 1", rooms: [] },
  ];

  jest.spyOn(namespaceAPI, "getNamespaces").mockImplementation(() => {
    return new Promise((resolve) => {
      resolve(mockNamespaces);
    });
  });

  SocketIOActions.loadNamespaces(mockSetNamespaces);

  expect(namespaceAPI.getNamespaces).toHaveBeenCalled();
  expect(mockSetNamespaces).toHaveBeenCalled();
});

从Jest收到错误消息:

● loadNamespaces

    expect(jest.fn()).toHaveBeenCalled()

    Expected number of calls: >= 1
    Received number of calls:    0

我也尝试过将setNamespaces添加到一个对象中,这样jest.spyOn方法就可以使用,但也没有Assert方法被调用:

test("loadNamespaces", () => {
  const mockObject = {
    mockSetNamespaces: jest.fn(),
  };

  const mockNamespaces = [
    { endpoint: "mock namespace 1", rooms: [] },
  ];

  jest.spyOn(namespaceAPI, "getNamespaces").mockImplementation(() => {
    return new Promise((resolve) => {
      resolve(mockNamespaces);
    });
  });

  jest.spyOn(mockObject, "mockSetNamespaces").mockImplementation(() => {
    console.log("Hello from spy function");
  });

  SocketIOActions.loadNamespaces(mockObject.mockSetNamespaces);

  expect(namespaceAPI.getNamespaces).toHaveBeenCalled();
  expect(mockObject.mockSetNamespaces).toHaveBeenCalled();
});

mock函数实际被调用的证明:

console.log
      Hello from spy function

这是Jest的预期行为吗?我很高兴知道是否有更干净的方法来做到这一点。

gjmwrych

gjmwrych1#

当您需要模拟模块中的特定函数而不是模拟所有函数时,请使用spyOn
我会这样做。

// this will help you auto mock all namespaceAPI function. If you just need to mock "getNamespaces" then you stick with spyOn
jest.mock('namespaceAPI')

test("loadNamespaces", () => {
  // you can directly mock implementation in jest function, dont need to spy it again.
  const mockSetNamespaces = jest.fn().mockImplementation(() => {
    console.log("Hello from spy function");
  });

  SocketIOActions.loadNamespaces(mockSetNamespaces);

  expect(namespaceAPI.getNamespaces).toHaveBeenCalled();
  expect(mockSetNamespaces).toHaveBeenCalled();
});

相关问题