【问题标题】:How to partially mock a custom react hook with Jest?如何使用 Jest 部分模拟自定义反应钩子?
【发布时间】:2021-06-03 13:38:27
【问题描述】:

我想用 Jest 模拟一些我的自定义 React 钩子返回值。 这是我正在尝试做的一个例子:

export default function useSongPlayer() {
  const playSongA = () => {...}
  const playSongB = () => {...}
  const playSongC = () => {...}

  return {
    playSongA,
    playSongB,
    playSongC,
  }
}

现在在我的测试中,我只想模拟 playSongA 并保持其他函数的真实实现。我尝试了几种方法,包括使用jest.requireActual('hooks/useSongPlayer'),但似乎playSongA 已成功模拟,而其他的只是未定义。

有了这样的东西,我很确定可以实现我想要的

export function playSongA() {...}

export function playSongB() {...}

export function playSongC() {...}

问题似乎是我尝试模拟的模块是一个函数,我想部分模拟这个函数的结果。

【问题讨论】:

    标签: reactjs unit-testing jestjs react-hooks mocking


    【解决方案1】:

    如果您创建一个返回原始值的模拟,但也拦截函数调用并替换其中一个值,这是可能的。

    您可以在没有Proxy 的情况下执行此操作,但我选择演示这一点,因为它是拦截实际钩子的任何使用的最完整方法。

    hooks/__mocks__/useSongPlayer.js

    // Get the actual hook
    const useSongPlayer = jest.requireActual('hooks/useSongPlayer');
    
    // Proxy the original hook so everything passes through except our mocked function call
    const proxiedUseSongPlayer = new Proxy(useSongPlayer, {
      apply(target, thisArg, argumentsList) {
        const realResult = Reflect.apply(target, thisArg, argumentsList);
        return {
          // Return the result of the real function
          ...realResult,
          // Override a single function with a mocked version
          playSongA: jest.fn(),
        };
      }
    });
    
    export default proxiedUseSongPlayer;
    

    【讨论】:

    • 感谢您的回答。我还没有尝试过,但出于好奇,如果没有代理,你会怎么做?
    • 如果您没有使用代理,您将不得不通过将函数替换为您自己的函数来拦截函数调用,并将所有参数传递给原始函数。我在这里使用代理是因为我不想升级 React,例如,因为某些极端情况而破坏您的测试。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-10
    • 2020-06-01
    • 1970-01-01
    • 2022-06-17
    • 2021-04-17
    • 2020-08-15
    • 2019-12-30
    相关资源
    最近更新 更多