【问题标题】:How do I mock next router in this custom hook?如何在此自定义挂钩中模拟下一个路由器?
【发布时间】:2020-04-19 22:35:48
【问题描述】:

我有一个在许多地方使用的自定义钩子,它拦截一个返回动作并调用传入的函数。我正在寻找验证在 beforePopState 内部调用了正确的函数。我将如何嘲笑这个?

const useBackNavigationIntercept = (action) => {
  const router = useRouter();

  useEffect(() => {
    router.beforePopState(() => {
      action();

      return false;
    });
  }, [action, router]);
};

我有一个测试,我试图模拟路由器,以便在路由中有一个特定的值,并且在调用钩子时调用适当的拦截操作。

例如测试使用钩子的组件:

import actions from '../../actions'

const SomeComponent = () => {
  ...
  const router = useRouter();
  const { country } = router.query;

  useBackNavigationIntercept(() => actions.someFunction(country));
  ...
}

并且想要验证 someFunction 是用 UK 作为参数调用的。

非常感谢这里的任何帮助,谢谢。

更新:

someFunction 被模拟如下:

import actions from '../../actions';
jest.mock('../../actions');
jest.mock('next/router', () => ({
  useRouter: jest.fn().mockImplementation(() => ({
    query: {
      country: 'UK',
    },
    beforePopState: require.requireActual('next/router'),
  })),
}));
...

// I'm expecting to be able to do something like this

it('calls someFunction with the correct args', () => {
  render(<SomeComponent {...props} />
  history.back();
  expect(actions.someFunction).toHaveBeenCalledWith('UK')
});

【问题讨论】:

  • someFunction 来自哪里?
  • someFunction 可以是任何东西,例如我可以在别处定义一个logout 函数并在钩子的回调中调用它
  • 你正在测试一个特定的组件,它使用你的自定义钩子,这个组件是从哪里获得 someFunction 的?
  • 我在另一个文件中有一个定义的可重用操作列表。我只是在测试中嘲笑它(更新以反映这一点)
  • SomeComponent 在哪里获得someFunction 函数?那里是硬编码的吗?它是通过进口获得的吗?

标签: javascript reactjs jestjs router next.js


【解决方案1】:

您需要模拟 ../actions 的导入并为其提供一个 spy 方法。

棘手的部分是测试中文件的导入顺序,因为您想在组件代码导入它之前模拟导入...

它应该看起来像:

// SomeComponent.spec.jsx
const actionsMock = {
  someFunction: jest.fn()
};

jest.mock('../../actions', () => actionsMock);
jest.mock('next/router', () => ({
  useRouter: jest.fn().mockImplementation(() => ({
    query: {
      country: 'UK',
    },
    beforePopState: jest.requireActual('next/router'),
  })),
}));

const SomeComponent = require('../path-to/SomeComponent')
// --------------------^ it should be required and not imported 
// because "import" must be the first thing in the file, and we have our mock definition

it('calls someFunction with the correct args', () => {
  render(<SomeComponent {...props} />;
  history.back();
  expect(actionsMock.someFunction).toHaveBeenCalledWith('UK');
});

【讨论】:

    猜你喜欢
    • 2021-11-22
    • 2022-01-27
    • 2023-01-18
    • 1970-01-01
    • 1970-01-01
    • 2022-11-30
    • 2018-02-05
    • 1970-01-01
    • 2021-11-22
    相关资源
    最近更新 更多