mirror of
https://github.com/callstack/react-native-testing-library.git
synced 2026-09-18 23:09:04 +08:00
1 line
13 KiB
JavaScript
1 line
13 KiB
JavaScript
"use strict";(self.rspackChunkwebsite=self.rspackChunkwebsite||[]).push([["4359"],{4474(e,n,r){r.r(n),r.d(n,{default:()=>t});var s=r(4848),i=r(8453);function a(e){let n={a:"a",blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",span:"span",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(n.h1,{id:"troubleshooting",children:[(0,s.jsx)(n.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#troubleshooting",children:"#"}),"Troubleshooting"]}),"\n",(0,s.jsx)(n.p,{children:"This guide describes common issues found by users when integrating React Native Test Library to their projects:"}),"\n",(0,s.jsxs)(n.h2,{id:"matching-react-native-react--react-test-renderer-versions",children:[(0,s.jsx)(n.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#matching-react-native-react--react-test-renderer-versions",children:"#"}),"Matching React Native, React & React Test Renderer versions"]}),"\n",(0,s.jsx)(n.p,{children:"Check that you have matching versions of core dependencies:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"React Native"}),"\n",(0,s.jsx)(n.li,{children:"React"}),"\n",(0,s.jsx)(n.li,{children:"React Test Renderer"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["React Native uses different versioning scheme from React, you can use ",(0,s.jsx)(n.a,{href:"https://react-native-community.github.io/upgrade-helper/",rel:"noopener noreferrer",target:"_blank",children:"React Native Upgrade Helper"})," to find the correct matching between React Native & React versions. In case you use Expo, run ",(0,s.jsx)(n.code,{children:"npx expo install --fix"})," in your project to validate and install compatible versions of these dependencies."]}),"\n",(0,s.jsxs)(n.p,{children:["React Test Renderer usually has same major & minor version as React, as they are closely related and React Test Renderer is part of ",(0,s.jsx)(n.a,{href:"https://github.com/facebook/react",rel:"noopener noreferrer",target:"_blank",children:"React monorepo"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Related issues: ",(0,s.jsx)(n.a,{href:"https://github.com/callstack/react-native-testing-library/issues/1061",rel:"noopener noreferrer",target:"_blank",children:"#1061"}),", ",(0,s.jsx)(n.a,{href:"https://github.com/callstack/react-native-testing-library/issues/938",rel:"noopener noreferrer",target:"_blank",children:"#938"}),", ",(0,s.jsx)(n.a,{href:"https://github.com/callstack/react-native-testing-library/issues/920",rel:"noopener noreferrer",target:"_blank",children:"#920"})]}),"\n",(0,s.jsx)(n.p,{children:"Errors that might indicate that you are facing this issue:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"TypeError: Cannot read property 'current' of undefined"})," when calling ",(0,s.jsx)(n.code,{children:"render()"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"TypeError: Cannot read property 'isBatchingLegacy' of undefined"})," when calling ",(0,s.jsx)(n.code,{children:"render()"})]}),"\n"]}),"\n",(0,s.jsxs)(n.h2,{id:"example-repository",children:[(0,s.jsx)(n.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#example-repository",children:"#"}),"Example repository"]}),"\n",(0,s.jsxs)(n.p,{children:["We maintain an ",(0,s.jsx)(n.a,{href:"https://github.com/callstack/react-native-testing-library/tree/main/examples/basic",rel:"noopener noreferrer",target:"_blank",children:"example repository"})," that showcases a modern React Native Testing Library setup with TypeScript, etc."]}),"\n",(0,s.jsx)(n.p,{children:"In case something does not work in your setup you can refer to this repository for recommended configuration."}),"\n",(0,s.jsxs)(n.h2,{id:"undefined-component-error",children:[(0,s.jsx)(n.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#undefined-component-error",children:"#"}),"Undefined component error"]}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsx)(n.p,{children:"Warning: React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined."}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"This frequently happens when you mock a complex module incorrectly, e.g.:"}),"\n",(0,s.jsx)(s.Fragment,{children:(0,s.jsx)(n.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"ts",children:(0,s.jsxs)(n.code,{children:[(0,s.jsxs)(n.span,{className:"line",children:[(0,s.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:"jest"}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:".mock"}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-token-string-expression)"},children:"'@react-navigation/native'"}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" () "}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"=>"}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" {"})]}),"\n",(0,s.jsxs)(n.span,{className:"line",children:[(0,s.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:" return"}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" {"})]}),"\n",(0,s.jsxs)(n.span,{className:"line",children:[(0,s.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" useNavigation"}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:":"}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:" jest"}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:".fn"}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"()"}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-token-punctuation)"},children:","})]}),"\n",(0,s.jsx)(n.span,{className:"line",children:(0,s.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" };"})}),"\n",(0,s.jsx)(n.span,{className:"line",children:(0,s.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"});"})})]})})}),"\n",(0,s.jsxs)(n.p,{children:["The above mock will mock ",(0,s.jsx)(n.code,{children:"useNavigation"})," hook as intended, but at the same time all other exports from ",(0,s.jsx)(n.code,{children:"@react-navigation/native"})," package are now ",(0,s.jsx)(n.code,{children:"undefined"}),". If you want to use ",(0,s.jsx)(n.code,{children:"NavigationContainer"})," component from the same package it will be ",(0,s.jsx)(n.code,{children:"undefined"})," and result in the error above."]}),"\n",(0,s.jsxs)(n.p,{children:["In order to mock only a part of given package you should re-export all other exports using ",(0,s.jsx)(n.code,{children:"jest.requireActual"})," helper:"]}),"\n",(0,s.jsx)(s.Fragment,{children:(0,s.jsx)(n.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"ts",children:(0,s.jsxs)(n.code,{children:[(0,s.jsxs)(n.span,{className:"line",children:[(0,s.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:"jest"}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:".mock"}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-token-string-expression)"},children:"'@react-navigation/native'"}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" () "}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"=>"}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" {"})]}),"\n",(0,s.jsxs)(n.span,{className:"line",children:[(0,s.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:" return"}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" {"})]}),"\n",(0,s.jsxs)(n.span,{className:"line",children:[(0,s.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:" ..."}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:"jest"}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:".requireActual"}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-token-string-expression)"},children:"'@react-navigation/native'"}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:")"}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-token-punctuation)"},children:","})]}),"\n",(0,s.jsxs)(n.span,{className:"line",children:[(0,s.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" useNavigation"}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:":"}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:" jest"}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:".fn"}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"()"}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-token-punctuation)"},children:","})]}),"\n",(0,s.jsx)(n.span,{className:"line",children:(0,s.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" };"})}),"\n",(0,s.jsx)(n.span,{className:"line",children:(0,s.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"});"})})]})})}),"\n",(0,s.jsxs)(n.p,{children:["That way the mock will re-export all of the ",(0,s.jsx)(n.code,{children:"@react-navigation/native"})," members and overwrite only the ",(0,s.jsx)(n.code,{children:"useNavigation"})," hook."]}),"\n",(0,s.jsxs)(n.p,{children:["Alternatively, you can use ",(0,s.jsx)(n.code,{children:"jest.spyOn"})," to mock package exports selectively."]}),"\n",(0,s.jsxs)(n.h3,{id:"mocking-react-native",children:[(0,s.jsx)(n.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#mocking-react-native",children:"#"}),"Mocking React Native"]}),"\n",(0,s.jsxs)(n.p,{children:["In case of mocking ",(0,s.jsx)(n.code,{children:"react-native"})," package you should not mock the whole package at once, as this approach has issues with ",(0,s.jsx)(n.code,{children:"jest.requireActual"})," call. In this case it is recommended to mock particular library paths inside the package, e.g.:"]}),"\n",(0,s.jsx)(s.Fragment,{children:(0,s.jsx)(n.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",title:"jest-setup.ts",lang:"ts",children:(0,s.jsx)(n.code,{children:(0,s.jsxs)(n.span,{className:"line",children:[(0,s.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:"jest"}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:".mock"}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-token-string-expression)"},children:"'react-native/Libraries/EventEmitter/NativeEventEmitter'"}),(0,s.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:");"})]})})})}),"\n",(0,s.jsxs)(n.h2,{id:"act-warnings",children:[(0,s.jsx)(n.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#act-warnings",children:"#"}),"Act warnings"]}),"\n",(0,s.jsxs)(n.p,{children:["When writing tests you may encounter warnings connected with ",(0,s.jsx)(n.code,{children:"act()"})," function. There are two kinds of these warnings:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["sync ",(0,s.jsx)(n.code,{children:"act()"})," warning - ",(0,s.jsx)(n.code,{children:"Warning: An update to Component inside a test was not wrapped in act(...)"})]}),"\n",(0,s.jsxs)(n.li,{children:["async ",(0,s.jsx)(n.code,{children:"act()"})," warning - ",(0,s.jsx)(n.code,{children:"Warning: You called act(async () => ...) without await"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["You can read more about ",(0,s.jsx)(n.code,{children:"act()"})," function in our ",(0,s.jsxs)(n.a,{href:"/13.x/docs/advanced/understanding-act.html",children:["understanding ",(0,s.jsx)(n.code,{children:"act"})," function guide"]}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Normally, you should not encounter sync ",(0,s.jsx)(n.code,{children:"act()"})," warnings, but if that happens this probably indicate an issue with your test and should be investigated."]}),"\n",(0,s.jsxs)(n.p,{children:["In case of async ",(0,s.jsx)(n.code,{children:"act()"})," function this might happen more or less randomly, especially if your components contain async logic. So far this warning does not seem to affect test correctness."]})]})}function t(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}t.__RSPRESS_PAGE_META={},t.__RSPRESS_PAGE_META["13.x%2Fdocs%2Fguides%2Ftroubleshooting.mdx"]={toc:[{id:"matching-react-native-react--react-test-renderer-versions",text:"Matching React Native, React & React Test Renderer versions",depth:2},{id:"example-repository",text:"Example repository",depth:2},{id:"undefined-component-error",text:"Undefined component error",depth:2},{id:"mocking-react-native",text:"Mocking React Native",depth:3},{id:"act-warnings",text:"Act warnings",depth:2}],title:"Troubleshooting",headingTitle:"Troubleshooting",frontmatter:{}}}}]); |