setTimeOut 内的模拟 console.error 未被调用

问题描述 投票:0回答:1

我正在嘲笑 console.error 函数来测试它是否被调用,测试工作到它在应该的地方出错并覆盖代码的正确部分,但是,当我断言控制台错误时测试失败应该被调用。

我之前已经这样做过并且它有效,但这是第一次在 setTimeOut 中,我认为这可能会以某种方式将其丢弃。

实际代码:

涵盖所有代码

   debounceTimeout = setTimeout(async () => {
      if (sessionId) {
        try {
          const res = await fetch(
            `${appConfig.url.BASE_URL}/${GET_SET_DATA_API}/category-set-data`,
            {
              method: "POST",
              credentials: "include",
              headers: {
                "Content-Type": "application/json",
                Cookie: `sessionId=${sessionId}`,
              },
              body: JSON.stringify({ state }),
            }
          );

          if (!res.ok) {
            // logs correctly
            console.error(`HTTP error! Status: ${res.status}`);
            throw new Error(`HTTP error! Status: ${res.status}`);
          }
        } catch (error) {
          console.error(`There was an error: ${error}`);
        }
      }
    }, delayTime);

测试:

describe("persist store", () => {
  let store: any;
  let state: RootState;

  beforeEach(() => {
    jest.clearAllMocks();
    store = makeStore();
    state = store.getState();
    global.fetch = jest.fn();
  });

  afterEach(() => {
    jest.restoreAllMocks();
  });

 it("should throw error if state cannot be stored", async () => {
    const sessionId = cookieMock.body.sessionId;
    const consoleErrorSpy = jest
      .spyOn(console, "error")
      .mockImplementation(() => {});
    jest.spyOn(global, "setTimeout");

(global.fetch as jest.Mock).mockResolvedValueOnce({
  ok: false,
  status: 500,
  statusText: "Session ID is required",
});

store.dispatch(setSessionId(sessionId));
jest.runAllTimers();

expect(setTimeout).toHaveBeenCalledTimes(1); // Works fine
expect(consoleErrorSpy).toHaveBeenCalled(); //not called even though the lines of code in the function are coverd

consoleErrorSpy.mockRestore();
  });
});

下面是一个可用于运行和更详细地查看问题的存储库: https://github.com/royadams72/jest-test-issue

typescript unit-testing jestjs
1个回答
0
投票

因此,当您打电话时,您并不是在伪造计时器

jest.runAllTimers();
它不做任何事情,当然只调用 setTimeout,而不是它的回调。

您必须在考试前致电

jest.useFakeTimers();

Jest time 模拟文档

© www.soinside.com 2019 - 2024. All rights reserved.