使用React-Testing-Library中的自定义/pages/_app. js测试Next.js应用

bxpogfeg  于 2023-04-11  发布在  React
关注(0)|答案(1)|浏览(130)

我尝试按照Reat-Testing-Library文档中的指南来 Package 所有我想要测试的组件。我这样做是因为我需要访问在我正在测试的组件中的_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中的<Component {...pageProps} />组件提供了pathName作为Next.js路由的一部分。
Next.js提供的示例没有涵盖如何做到这一点,所以我希望这里的人能够提供帮助。

h9vpoimq

h9vpoimq1#

您是否已经尝试从/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 (
      <ApolloProvider client={apolloClient}>
        <CssBaseline />
        {React.cloneElement(children, { pageProps })}
        <SignUp />
        <Snackbar />
      </ApolloProvider>
    );
  }
}
const AllTheProviders = withApollo(AllTheProvidersWrapped);

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

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

我认为,Context提供程序只在**_app.js**文件上工作,它是Next.js的东西。

相关问题