如果 React-Error-Boundary 从错误中恢复,如何编写测试?

问题描述

我的应用程序从 API 获取数据,然后呈现数据。如果输入了不存在的值,则 error boundary 会触发并捕获错误

我正在使用 ErrorBoundary 库中的 react-error-boundaryQueryErrorResetBoundary 库中的 react-query

通过我的 React-Error-Boundary 设置,我的应用程序在发生 error boundary 时有一个 error 触发器,并且能够通过重置 errorstate 中恢复。我目前对 error boundary 发生时的 error 触发进行了通过测试。现在我想测试 error boundary 是否可以从触发的 error boundary 中恢复并重置 state。请告诉我如何使用 JestReact Testing Library

应用组件

const ErrorFallback = ({ error,resetErrorBoundary }) => {
  return (
    <div role="alert">
      <p>Something went wrong:</p>
      <pre style={{ color: "red" }}>{error.message}</pre>
      <button onClick={resetErrorBoundary}>Try again</button>
    </div>
  );
};

const App = () => {
  const [idQuery,setIdQuery] = useState(0);

  return (
    <div>
      <QueryErrorResetBoundary>
        <ErrorBoundary
          FallbackComponent={ErrorFallback}
          onReset={() => {
            setIdQuery(0);
          }}
          resetKeys={[idQuery]}
        >
          <Home idQuery={idQuery} setIdQuery={setIdQuery} />
        </ErrorBoundary>
      </QueryErrorResetBoundary>
      <ReactQueryDevtools initialIsOpen={true} />
    </div>
  );
};

App.test.js

const App = () => {
    const [state,setState] = useState(0)
    return (
        <QueryErrorResetBoundary>
            <ErrorBoundary
                FallbackComponent={ErrorFallback}
                onReset={() => {
                    setState(0);
                }}
                resetKeys={[state]}
            >
                <Child />
            </ErrorBoundary>
        </QueryErrorResetBoundary>
    )
}

const Child = () => {
    throw new Error()
}

describe("Error Boundary",() => {
    beforeEach(() => {
        render(
            <App />
        );
    });

    it("should trigger the Error Boundary when an error occurs",() => {
        const errorMessage = screen.getByTestId("error-boundary-message");
        expect(errorMessage).toBeInTheDocument();
    });

    it("should recover from Error Boundary",() => {
        // ???
    })

});

解决方法

在不知道您实际要做什么的情况下,我怀疑这样的事情可能会帮助您入门:

const App = () => {
    const [isRecovered,setIsRecovered] = useState(false)
    return (
        <QueryErrorResetBoundary>
            <ErrorBoundary
                FallbackComponent={ErrorFallback}
                onReset={() => {
                    setIsRecovered(true)
                }}
                resetKeys={[isRecovered]}
            >
                <Child isRecovered={isRecovered} />
            </ErrorBoundary>
        </QueryErrorResetBoundary>
    )
}

const Child = ({isRecovered}) => {
    if(!isRecovered) throw new Error();
    return 'All Good';
}

至少您可以将 ErrorBoundary 的代码添加到您的问题中。