【问题标题】:Testing a Next.js app with a custom /pages/_app.js in React-Testing-Library在 React-Testing-Library 中使用自定义 /pages/_app.js 测试 Next.js 应用程序
【发布时间】:2019-09-23 15:36:39
【问题描述】:

我正在尝试关注this guide in Reat-Testing-Library documentation 来包装我想要测试的所有组件。我这样做是因为我需要访问在我正在测试的组件中的 _app.js 中定义的各种上下文提供程序。

这是我的 /pages/_app.js 文件:

export class MyApp extends App {
  public componentDidMount() {
    const jssStyles = document.querySelector("#jss-server-side");
    if (jssStyles && jssStyles.parentNode) {
      jssStyles.parentNode.removeChild(jssStyles);
    }
  }
  public render() {
    const { Component, pageProps, apolloClient } = this.props;
    return (
      <Container>
        <StateProvider>
          <ThemeProvider theme={theme}>
            <ApolloProvider client={apolloClient}>
              <CssBaseline />
              <Component {...pageProps} />
              <SignUp />
              <Snackbar />
            </ApolloProvider>
          </ThemeProvider>
        </StateProvider>
      </Container>
    );
  }
}

export default withApollo(MyApp);

这是我的 /utils/testProviders.js 文件:

class AllTheProvidersWrapped extends App {
  public componentDidMount() {
    const jssStyles = document.querySelector("#jss-server-side");
    if (jssStyles && jssStyles.parentNode) {
      jssStyles.parentNode.removeChild(jssStyles);
    }
  }
  public render() {
    const { pageProps, apolloClient, children } = this.props;
    return (
      <Container>
        <StateProvider>
          <ThemeProvider theme={theme}>
            <ApolloProvider client={apolloClient}>
              <CssBaseline />
              {React.cloneElement(children, { pageProps })}
              <SignUp />
              <Snackbar />
            </ApolloProvider>
          </ThemeProvider>
        </StateProvider>
      </Container>
    );
  }
}
const AllTheProviders = withApollo(AllTheProvidersWrapped);

const customRender = (ui, options) =>
  render(ui, { wrapper: AllTheProviders, ...options });

export * from "react-testing-library";
export { customRender as render };

这是我的 /jest.config.js 文件:

module.exports = {
  testPathIgnorePatterns: ["<rootDir>/.next/", "<rootDir>/node_modules/"],
  moduleDirectories: ["node_modules", "utils", __dirname]
};

这是我尝试运行的测试示例:

import React from "react";
import { render, cleanup } from "testProviders";

import OutlinedInput from "./OutlinedInput";

afterEach(cleanup);

const mockProps = {
  id: "name",
  label: "Name",
  fieldStateString: "signUpForm.fields"
};

describe("<OutlinedInput />", (): void => {
  it("renders as snapshot", (): void => {
    const { asFragment } = render(<OutlinedInput {...mockProps} />, {});
    expect(asFragment()).toMatchSnapshot();
  });
});

测试输出的错误信息是:

    TypeError: Cannot read property 'pathname' of undefined

      52 | 
      53 | const customRender: CustomRender = (ui, options) =>
    > 54 |   render(ui, { wrapper: AllTheProviders, ...options });
         |   ^
      55 | 
      56 | // re-export everything
      57 | export * from "react-testing-library";

如果我不得不猜测,我会说 /pages/_app.js 中的 &lt;Component {...pageProps} /&gt; 组件是提供路径名作为 Next.js 路由的一部分。

Next.js 提供的示例并未涵盖如何执行此操作,因此我希望这里的人能够提供帮助。

【问题讨论】:

  • 你解决过这个问题吗,@GCM?
  • 不 :( 不幸的是,我必须在 Next.js 上下文之外运行测试。
  • 我也想知道如何编写测试来测试页面的呈现。测试简单的组件很简单,但是页面依赖于 HOC 或复杂的设置,如 req/res、apollo 等。例如,测试 _app 并不是那么简单……但我也想知道测试这些东西是否有趣单元测试,我正在考虑将赛普拉斯用于“视觉”测试(工作流程、导航)的所有内容,并为更简单的内容保留单元测试。 (纯成分)

标签: jestjs next.js react-testing-library


【解决方案1】:

查看next-page-tester 库。它非常新,但它是我发现的唯一可以帮助测试 Next.js 页面组件的东西。

【讨论】:

    猜你喜欢
    • 2023-03-13
    • 2021-04-25
    • 1970-01-01
    • 2019-05-21
    • 2019-11-11
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 2021-10-22
    相关资源
    最近更新 更多