【问题标题】:How to test custom React-query hook that is based on Firebase methods?如何测试基于 Firebase 方法的自定义 React-query 钩子?
【发布时间】:2021-12-30 13:10:05
【问题描述】:

我遇到了 react-query-firebase,它们是基于 React-query for firebase 构建的钩子。

我还发现了名为 mock service worker https://mswjs.io/ 的库,但它基于 REST 和 GraphQL。

这是我如何使用这些钩子的示例代码:

import React from "react";
import { useFirestoreDocument } from "@react-query-firebase/firestore";
import {
  doc
} from "firebase/firestore";
import { firestore } from "../firebase";

function GetUser() {
  const id = "pW5CizOJOpXezr5lGGshDmKdVpP3";
  const ref = doc(firestore, "users", id);
  const user = useFirestoreDocument(["users", id], ref);

  return (
    <div>
      {user.isLoading && <div>Loading...</div>}
      {user.data && <div>{user.data.data()?.name}</div>}
    </div>
  );
}

export default GetUser;

我是测试新手,我不知道如何执行这个测试,因为我在模拟请求,我可以使用随机 url 还是必须是与 firebase 相关的方法?

【问题讨论】:

    标签: reactjs firebase testing jestjs react-query


    【解决方案1】:

    react-query-firebase 库是对 Firebase 的抽象,它封装了资源路径(我相信它是一个 SDK)。由于路径(URL)是从中抽象出来的,因此您至少有两个选项可以模拟此类库发出的请求。

    选项 1:使用显式路径

    尽管确切的资源路径被隐藏起来,请求仍然引用现有的绝对路径。您可以在浏览器的“网络”选项卡中观察这些内容,也可以使用 msw 启用简单的请求自省:

    // my.test.js
    import { setupServer } from 'msw/node'
    
    const server = setupServer(/* no handlers */)
    
    beforeAll(() => server.listen())
    afterAll(() => server.close())
    

    由于我们使用没有处理程序的setupServer,所以在my.test.js 中发生的所有请求都将作为警告打印到stderr。您可以观察这些警告以查看您的 SDK 请求的资源路径。

    使用 SDK 的好处是它可以保证您有一定的资源路径结构。最有可能的是,您将能够在您的模拟中复制该结构:

    // src/mocks.js
    import { rest } from 'msw'
    
    export const handlers = [
      rest.get('https://some-resource.:checksum.firebase.app/path', (req, res, ctx) => res(ctx.text('hello)))
    ]
    
    

    利用:checksum 等动态路径段来匹配更广泛的路径。

    这种方法的缺点是您的模拟定义变得依赖于 SDK 内部详细信息(资源路径)。 SDK 的任何更新都可能会破坏您的模拟,因为它们可能会在内部更新路径结构而不将其表示为重大更改(抽象路径不是公共 API)。

    选项 2:监视 SDK

    或者,您可以监视您正在使用的 SDK。这种间谍的一个例子是直接在react-query-firebase 上使用jest.spyOn

    // my.test.js
    import * as reactQueryFirebase from 'react-query-firebase'
    
    it('creates a user', () => {
      jest.spyOn(reactQueryFirebase, 'SOME_METHOD_NAME')
        .mockReturnValue(/* mock */)
    })
    

    这种方法的缺点是您要从第三方库中存根函数,这意味着您的测试代码永远不会调用这些函数。这会降低此类测试的可靠性,您通常应该避免使用这种方法。

    我建议您研究 Firebase,因为主要的 SDK 提供商通常都有关于模拟其 API 的指南。通常这样的指导将包括使用由 SDK 提供商编写的专用第三方包,允许模拟其内部资源。

    【讨论】:

      猜你喜欢
      • 2020-02-19
      • 2021-04-25
      • 1970-01-01
      • 2021-04-17
      • 1970-01-01
      • 2021-03-10
      • 2023-03-13
      • 2022-08-18
      • 1970-01-01
      相关资源
      最近更新 更多