当前位置: 首页 > 知识库问答 >
问题:

如何模拟要测试的React组件内部的自定义钩子?

巩子实
2023-03-14

如果您有一个调用获取数据的自定义钩子的React组件,在测试React组件时,模拟内部自定义钩子结果的最佳方法是什么?我看到了两种主要的方法:

1)Jest.mock自定义钩子。这似乎是最值得推荐的方法,但它似乎需要测试对内部实现细节以及它可能需要模拟的内容有更多的了解,而不是组件的道具接口可能建议的内容(假设使用道具类型或TypeScript)

2) 使用依赖注入方法。将钩子声明为道具,但将其默认为真实钩子,这样您就不必在渲染组件的任何地方都设置钩子,而是允许使用模拟覆盖以进行测试。下面是一个虚构的codesandbox示例,其中有一个模拟自定义挂钩的测试:

https://codesandbox.io/s/dependency-inject-custom-hook-for-testing-mjqlf?fontsize=14

2需要更多的输入,但似乎更容易用于测试。然而,测试必须了解组件的内部实现细节,才能测试渲染输出的任何条件逻辑,所以这可能并不重要,1是最好的方法。1路走吗?你看到了什么权衡?我是否完全错过了另一种方法?

共有3个答案

荆梓
2023-03-14

你为什么不嘲笑一下进行api调用的底层方法呢?

例如,如果您正在使用fetch()检索数据,您可以模拟它。通过这种方式,您可以为该调用定义自定义响应,这将使测试挂钩本身变得简单。

舒飞捷
2023-03-14

这个问题已经有几个月了,但是如果你还没有找到一个好的解决方案,我写了一个可能会有所帮助的包。我经历了类似的思考过程,包括“如果我把钩子注入组件呢?”事情变得很奇怪。

我基本上想要一个连接器,以避免仅仅为了测试它们而为表现性组件提供额外的包装。

我提出了react hooks compose,它允许您将挂钩和演示者分开,并单独或一起进行测试:https://www.npmjs.com/package/react-hooks-compose

export const useFetch = () => {
  const [user, setUser] = useState();

  useEffect(() => {
    fetchData('some-url') // <-- Fetches data on mount
      .then(res => setUser(res.data));
  }, []);

  return {user};
}

// composeHooks passes the values from your hooks as props
export const UserPresenter = ({user}) => {
  return <div>You fetched data for: {user.name}</div>;
}

export default composeHooks({ useFetch })(DataPresenter);

现在,您不必模拟挂钩,只需使用道具测试演示者:

it('presents user', () => {
  const { queryByText } = render(<UserPresenter user={{name: 'Mary'}} />); // <-- Named export
  expect(queryByText('Mary')).toBeTruthy();
});

或者,您可以选择更高级别的集成测试:

it('fetches data', () => {
  fetchData.mockResolvedValue('Mary');
  const { queryByText } = render(<UserWithData />); // <-- Default export
  expect(queryByText('Mary')).toBeFalsy();
  return wait(() => {
    expect(queryByText('Mary')).toBeTruthy();
  });
});

如果你愿意,你甚至可以对钩子进行单元测试。

洪德寿
2023-03-14

使用笑话模仿您的自定义钩子。

import * as useCustomHook from '../hooks/useCustomHooks'

const spy = jest.spyOn(useCustomHook, 'default')
spy.mockReturnValue({
name: 'test'
})
 类似资料:
  • 问题内容: 我有一个使用的组件,然后它的输出取决于上下文中的值。一个简单的例子: 当使用来自react和jest快照的浅色渲染器测试此组件时。如何更改值? 问题答案: 通常,使用钩子应该不会改变测试策略。实际上,这里更大的问题不是问题,而是上下文的使用,这使事情变得有些复杂。 有很多方法可以使这项工作,但是我发现唯一可以使用的方法是注入一个模拟钩子: 但是,这有点脏,并且是特定于实现的,因此,如果

  • 问题内容: 我正在用Java编程,而我的应用程序正在大量使用DB。因此,对我来说重要的是能够轻松测试数据库的使用情况。 什么是DB测试?对我来说,他们应该提供两个简单的要求: 验证SQL语法。 更重要的是,根据给定情况检查数据是否正确选择/更新/插入。 那么,看来我只需要一个DB。 但实际上,我不喜欢这样做,因为使用数据库进行测试几乎没有困难: “只给自己一个测试数据库,这有多难?” -嗯,在我的

  • 上面的测试示例不起作用,但用于演示我试图实现的目标。并实际呈现0 div,因为组件中声明的初始状态包含0项。 > 为了测试的目的,我应该如何修改一个reducer的状态或者更改它部署时的initialState? 我习惯于在多个组件中使用Redux还原程序,但是useReducer需要一个传递的initialState。。。这就提出了一个问题:react-hook的reducer是作为一个实例通过

  • 问题内容: Jest提供了一种模拟函数的方法,如其文档中所述 但是,这些模拟仅在直接在测试中调用函数时才起作用。 如果我有一个这样定义的React Component,该如何模拟呢? 我不知道如何制作它,所以组件调用了我的模拟实现,以便我可以测试它是否可以正确地呈现数据。 (这是一个简化的,人为的示例,目的是为了了解如何模拟在React组件内部调用的函数) 编辑:api.js文件,为清楚起见 问题

  • 问题内容: 我有一个要测试的类。只要有可能,我都会对该类进行依赖注入,该注入依赖于其他类的对象。但是,我遇到了一种情况,我想在不重新构造代码的情况下模拟对象,而不是应用DI。 这是要测试的课程: 我为此的测试课程是: 我想不出一种解决方案来模拟Dealer类中的打印对象。自从我在Test类中对其进行了模拟,但是它是在被测试的方法中创建的。我做了研究,但找不到任何好处。资源。 我知道从该方法中创建P

  • 我在camel Kafka starter依赖项中使用了一个Kafka组件。在这个问题中,建议我使用“定制器”。我将如何在spring boot应用程序中使用它?