【问题标题】:Can't find "client" in testing after wrapping the root component in an <ApolloProvider>将根组件包装在 <ApolloProvider> 中后,在测试中找不到“客户端”
【发布时间】:2020-11-05 04:51:50
【问题描述】:

我有一个带有 React 和 Apollo Client 的前端,正在尝试编写一些简单的测试。

我的应用如下所示:

ApolloProvider.js

import React from "react"
import App from "./App"
import ApolloClient from "apollo-client"
import { InMemoryCache } from "apollo-cache-inmemory"
import { createHttpLink } from "apollo-link-http"
import { ApolloProvider } from "@apollo/react-hooks"
import { setContext } from "apollo-link-context"

const httpLink = createHttpLink({
  uri: "...backend....",
})

const authLink = setContext(() => {
  const token = localStorage.getItem("jwtToken")
  return {
    headers: {
      Authorization: token ? `Bearer ${token}` : "",
    },
  }
})

const client = new ApolloClient({
  link: authLink.concat(httpLink),
  cache: new InMemoryCache(),
})

export default (
  <ApolloProvider client={client}>
    <App />
  </ApolloProvider>
)

App.js

import React from "react"

import { BrowserRouter as Router, Route } from "react-router-dom"
import { Container } from "semantic-ui-react"

import "semantic-ui-css/semantic.min.css"
import "./App.css"

import { AuthProvider } from "./context/auth"
import AuthRoute from "./util/AuthRoute"

import MenuBarTop from "./components/MenuBarTop"

import Home from "./pages/Home"
import Login from "./pages/Login"
import Register from "./pages/Register"
import SingleQuote from "./pages/SingleQuote"

function App() {
  return (
    <AuthProvider>
      <Router className="App">
        {/* or <div class='ui container' ... */}
        <Container>
          <MenuBarTop />
          <Route exact path="/" component={Home} />
          <AuthRoute exact path="/login" component={Login} />
          <AuthRoute exact path="/register" component={Register} />
          <Route exact path="/quotes/:quoteId" component={SingleQuote} />
        </Container>
      </Router>
    </AuthProvider>
  )
}

export default App

App.test.js

import React from "react"
import { render } from "@testing-library/react"
import App from "./App"

test("renders home headers", () => {
  const { getByText } = render(<App />)
  const HomeHeader = getByText("Recent Quotes")
  expect(HomeHeader).toBeInTheDocument()
})

我在 Home.js 组件中遇到错误:

  Invariant Violation: Could not find "client" in the context or passed in as an option. Wrap the root component in an <ApolloProvider>, or pass an ApolloClient instance in via options.

      10 | function Home() {
      11 |   const { user } = useContext(AuthContext)
    > 12 |   const { loading, data } = useQuery(FETCH_QUOTES_QUERY)
         |                             ^
      13 | 
      14 |   let quotes = []
      15 | 

我关注了关于MockedProvider 的类似问题的帖子,并在那里测试了建议的解决方案并尝试添加@apollo/react-testing

我也尝试在测试中使用较低的组件(Home),但得到了同样的错误。

我的包裹是这样的:

name": "client",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@apollo/react-hooks": "^3.1.5",
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.3.2",
    "@testing-library/user-event": "^7.1.2",
    "apollo-cache-inmemory": "^1.6.5",
    "apollo-client": "^2.6.8",
    "apollo-link-context": "^1.0.20",
    "apollo-link-http": "^1.5.17",
    "dotenv": "^8.2.0",
    "graphql": "^15.0.0",
    "graphql-tag": "^2.10.3",
    "jwt-decode": "^2.2.0",
    "moment": "^2.24.0",
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "react-router-dom": "^5.1.2",
    "react-scripts": "3.4.1",
    "semantic-ui-css": "^2.4.1",
    "semantic-ui-react": "^0.88.2"
  },

React Uncaught Invariant Violation: Could not find "client" in the context of ApolloConsumer. Wrap the root component in an 的评论表明,当使用“仅react-apollo 而不是react-apollo@apollo/react-hooks”时可能会发生错误。

但是,我只使用@apollo/react-hooks

回购已开放,在此处:https://github.com/moritzWa/mentorcards-client

【问题讨论】:

    标签: reactjs apollo react-apollo apollo-client react-testing-library


    【解决方案1】:

    您可以使用MockProviderreact-testing-library 来测试您的反应组件。阅读更多关于MockProviderhere的信息。

    试试这个:

    import { act, fireEvent, render } from '@testing-library/react'
    import { MockedProvider } from '@apollo/react-testing'
    
    import YourComponent from './path'
    
    const mocks = [
        {
            request: {
                query: Todo,
                variables: {
                    query: { name },
                },
            },
            result: {
                data: {
                    mockData_here
                },
            },
        },
    ]
    
    test('it should ...', () => {
      let rendered
      await act(async () => {
        rendered = render(
          <MockedProvider mocks={mocks} addTypename={false}>
              {YourComponent}
          </MockedProvider>
        )
      })
      expect(rendered).toMatchSnapshot()
    })

    【讨论】:

      【解决方案2】:

      我有类似的问题。我使用了两个包@apollo/client 和@apollo/react-hoc。 我从@apollo/client 获取 { Client }。我还使用了来自@apollo/react-hoc 的 { withApollo }。这创建了两个不同的上下文。我读到我可以替换 “旧:@apollo/react-hoc --> 新:@apollo/client/react/hoc”,它解决了我的错误。

      【讨论】:

        猜你喜欢
        • 2020-03-21
        • 2021-04-19
        • 2016-05-19
        • 2022-06-29
        • 2017-02-25
        • 2021-11-09
        • 1970-01-01
        • 2020-05-13
        • 1970-01-01
        相关资源
        最近更新 更多