【问题标题】:useQuery: Cannot spy the useQuery property because it is not a functionuseQuery:无法监视 useQuery 属性,因为它不是函数
【发布时间】:2022-01-11 01:52:27
【问题描述】:

有一个像这样的简单 useQuery

  const {
    isLoading, isError, data,
  } = useQuery(['courses', { userId: someUserId }], fetchDataFromBackendServer);

在我的单元测试中,我希望从一开始就使用 useQuery 返回信息(我想这样做是有原因的,但这不是主题)

  describe.only('Title', () => {
    beforeEach(() => {
      jest.clearAllMocks();
      jest.spyOn(React, 'useQuery').mockResolvedValue({ isError: false, isLoading: false });
    }
    ...
  }

它给了我:无法监视 useQuery 属性,因为它不是函数;取而代之的是未定义

请解决这个问题?

【问题讨论】:

  • React-Query 有 a testing library 和有关如何使用它的文档。不确定它如何与 jest 交互,但至少是一个开始。

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


【解决方案1】:

首先,React 不提供useQuery 钩子。

我猜你正在使用react-query

第二个,如果要使用jest.spyOn(obj, 'method'),不能从obj中析构方法。这意味着您应该在组件中像 ReactQuery.useQuery() 一样使用它。

例如

import { render } from '@testing-library/react';
import React from 'react';
import * as ReactQuery from 'react-query';

describe('70660790', () => {
  test('should pass', () => {
    jest.spyOn(ReactQuery, 'useQuery').mockImplementation();
    function Test() {
      ReactQuery.useQuery('todos');
      return null;
    }
    render(<Test />);
    expect(ReactQuery.useQuery).toBeCalledWith('todos');
  });
});

测试结果:

 PASS  examples/70660790/index.test.tsx (11.646 s)
  70660790
    ✓ should pass (18 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        13.036 s

看看react-queryexports如何在桶文件中挂钩,我们必须使用命名空间导入。

最后,你不应该模拟useQuery钩子第三方包提供,并测试实现细节。您应该继续使用原始的useQuery 钩子和模拟副作用函数,例如fetchDataFromBackendServer(我想这是对远程服务器的API 调用)。然后你可以测试组件的输出是什么。 见testing

同样,不推荐模拟useQuery。模拟实现可能与原始实现不一致,这将导致您的测试建立在错误的模拟实现上。这会导致您的测试用例通过,但程序在运行时不正确。

而且,测试实现细节也可能使测试用例易受攻击。 实现细节的微小变化将导致测试用例失败,您将不得不修改测试用例。

【讨论】:

  • 这很有意义。关于第二项,我使用了 jest.spyOn(ReactQuery, 'useQuery').mockReturnValue(),仍然得到:Cannot spyOn on a original value。为什么是这样 ?我改变了主代码和单元测试
  • 顺便说一句,我坚持要模拟 useQuery 以返回即时值 bcz 来自 react-test-library 的 useEffect 上的另一个错误,仅供参考
  • @user3552178 更新答案
  • 好一个,这是“import * as ReactQuery”的关键,谢谢!
  • @user3552178 同样,你最好不要嘲笑useQuery
猜你喜欢
  • 1970-01-01
  • 2022-10-20
  • 1970-01-01
  • 2022-07-28
  • 1970-01-01
  • 2020-08-20
  • 2020-09-14
  • 2020-09-02
  • 2020-01-06
相关资源
最近更新 更多