Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jest TypeError: Cannot read properties of undefined (reading 'width') #5820

Open
5 tasks
toninlopes opened this issue Oct 28, 2024 · 1 comment
Open
5 tasks

Comments

@toninlopes
Copy link

Description

Testing Snapshot NativeBase components failed

CodeSandbox/Snack link

https://github.com/toninlopes/NativeBaseSample

Steps to reproduce

  1. On terminal, run yarn test

NativeBase Version

3.4.28

Platform

  • Android
  • CRA
  • Expo
  • iOS
  • Next

Other Platform

No response

Additional Information

I have set up a standard React Native + Native Base project. See the package.json.

{
  "name": "NativeBaseSample",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "android": "react-native run-android",
    "ios": "react-native run-ios",
    "lint": "eslint .",
    "start": "react-native start",
    "test": "jest"
  },
  "dependencies": {
    "native-base": "^3.4.28",
    "react": "18.3.1",
    "react-native": "0.76.0",
    "react-native-safe-area-context": "3.3.2",
    "react-native-svg": "12.1.1"
  },
  "devDependencies": {
    "@babel/core": "^7.25.2",
    "@babel/preset-env": "^7.25.3",
    "@babel/runtime": "^7.25.0",
    "@react-native-community/cli": "15.0.0-alpha.2",
    "@react-native-community/cli-platform-android": "15.0.0-alpha.2",
    "@react-native-community/cli-platform-ios": "15.0.0-alpha.2",
    "@react-native/babel-preset": "0.76.0",
    "@react-native/eslint-config": "0.76.0",
    "@react-native/metro-config": "0.76.0",
    "@react-native/typescript-config": "0.76.0",
    "@testing-library/react-native": "^12.8.0",
    "@types/react": "^18.2.6",
    "@types/react-test-renderer": "^18.0.0",
    "babel-jest": "^29.6.3",
    "eslint": "^8.19.0",
    "jest": "^29.6.3",
    "prettier": "2.8.8",
    "react-test-renderer": "18.3.1",
    "typescript": "5.0.4"
  },
  "engines": {
    "node": ">=18"
  }
}

Here is a simple snapshot test with @testing-library/react-native and react-test-renderer.

import 'react-native';
import React from 'react';
import {describe, it, expect} from '@jest/globals';
import {render, screen} from '@testing-library/react-native';
import renderer from 'react-test-renderer';
import { Button } from 'native-base';
import { Text } from 'react-native';
import { NativeBaseProvider } from 'native-base';
import { Metrics, SafeAreaProvider } from 'react-native-safe-area-context';

const MOCK_INITIAL_METRICS: Metrics = {
  frame: { width: 320, height: 640, x: 0, y: 0 },
  insets: { left: 0, right: 0, bottom: 0, top: 0 },
};

const Wrapper = ({children}: {children: React.ReactNode}) =>
  <SafeAreaProvider initialMetrics={MOCK_INITIAL_METRICS}>
    <NativeBaseProvider>
      {children}
    </NativeBaseProvider>
  </SafeAreaProvider>;


describe('Snapshot Testing', () => {

  it('Render NativeBase Button with @testing-library/react-native', () => {
    render(
      <Wrapper>
        <Button>Test</Button>
      </Wrapper>
    );
    expect(screen.toJSON()).toMatchSnapshot();
  });

  it('Render NativeBase Button with react-test-renderer', () => {
    const component = renderer.create(
      <Wrapper>
        <Button>Test</Button>
      </Wrapper>
    ).toJSON();
    expect(component).toMatchSnapshot();
  });

  it('Render React Native Text with @testing-library/react-native', () => {
    render(
      <Text>Test</Text>
    );
    expect(screen.toJSON()).toMatchSnapshot();
  });

  it('Render React Native Text with react-test-renderer', () => {
    const component = renderer.create(
      <Text>Test</Text>
    ).toJSON();
    expect(component).toMatchSnapshot();
  });

});

Tests 1 and 2 use the <NativeBaseProvider /> as wrapper and both libraries gets the same error.

console.error
    The above error occurred in the <ForwardRef> component:
    
        at debug (/Users/aclopesjr/git_repos/ReactNative/NativeBaseSample/node_modules/native-base/lib/commonjs/utils/styled.js:18:5)
        at children (/Users/aclopesjr/git_repos/ReactNative/NativeBaseSample/node_modules/native-base/lib/commonjs/components/primitives/Pressable/Pressable.js:72:3)
        at children (/Users/aclopesjr/git_repos/ReactNative/NativeBaseSample/node_modules/native-base/lib/commonjs/components/primitives/Button/Button.js:38:3)
        at children (/Users/aclopesjr/git_repos/ReactNative/NativeBaseSample/node_modules/@react-aria/ssr/dist/SSRProvider.main.js:75:154)
        at children (/Users/aclopesjr/git_repos/ReactNative/NativeBaseSample/node_modules/native-base/lib/commonjs/components/composites/Toast/Toast.js:139:3)
        at useState (/Users/aclopesjr/git_repos/ReactNative/NativeBaseSample/node_modules/@react-native-aria/overlays/lib/commonjs/Portal.js:17:44)
        at children (/Users/aclopesjr/git_repos/ReactNative/NativeBaseSample/node_modules/native-base/lib/commonjs/core/hybrid-overlay/HybridProvider.js:23:3)
        at disableCSSMediaQueries (/Users/aclopesjr/git_repos/ReactNative/NativeBaseSample/node_modules/native-base/lib/commonjs/utils/useResponsiveQuery/ResponsiveQueryProvider.js:21:14)
        at RNCSafeAreaProvider
        at Component (/Users/aclopesjr/git_repos/ReactNative/NativeBaseSample/node_modules/react-native/jest/mockNativeComponent.js:17:18)
        at children (/Users/aclopesjr/git_repos/ReactNative/NativeBaseSample/node_modules/react-native-safe-area-context/lib/commonjs/SafeAreaContext.js:35:3)
        at children (/Users/aclopesjr/git_repos/ReactNative/NativeBaseSample/node_modules/native-base/lib/commonjs/utils/createContext.js:17:7)
        at colorModeManager (/Users/aclopesjr/git_repos/ReactNative/NativeBaseSample/node_modules/native-base/lib/commonjs/core/NativeBaseProvider.js:56:5)
        at RNCSafeAreaProvider
        at Component (/Users/aclopesjr/git_repos/ReactNative/NativeBaseSample/node_modules/react-native/jest/mockNativeComponent.js:17:18)
        at children (/Users/aclopesjr/git_repos/ReactNative/NativeBaseSample/node_modules/react-native-safe-area-context/lib/commonjs/SafeAreaContext.js:35:3)
        at children (/Users/aclopesjr/git_repos/ReactNative/NativeBaseSample/__tests__/App.test.tsx:16:19)
    
    Consider adding an error boundary to your tree to customize error handling behavior.
    Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.

      25 |
      26 |   it('Render NativeBase Button with @testing-library/react-native', () => {
    > 27 |     render(
         |           ^
      28 |       <Wrapper>
      29 |         <Button>Test</Button>
      30 |       </Wrapper>

      at logCapturedError (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:8678:23)
      at logCapturedError (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:8711:5)
      at call (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5175:12)
      at callCallback (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5196:9)
      at commitUpdateQueue (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:13271:13)
      at commitLayoutEffectOnFiber (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:14369:9)
      at commitLayoutMountEffects_complete (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:14355:7)
      at commitLayoutEffects_begin (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:14340:3)
      at commitLayoutEffects (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:16101:5)
      at commitRootImpl (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15972:5)
      at commitRoot (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15493:3)
      at callback (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22)
      at callback (node_modules/react/cjs/react.development.js:2667:24)
      at flushActQueue (node_modules/react/cjs/react.development.js:2521:11)
      at actImplementation (node_modules/@testing-library/react-native/build/act.js:31:25)
      at renderWithAct (node_modules/@testing-library/react-native/build/render-act.js:14:24)
      at renderInternal (node_modules/@testing-library/react-native/build/render.js:54:48)
      at renderInternal (node_modules/@testing-library/react-native/build/render.js:29:10)
      at Object.<anonymous> (__tests__/App.test.tsx:27:11)

  console.error
    The above error occurred in the <ForwardRef> component:
    
        at debug (/Users/aclopesjr/git_repos/ReactNative/NativeBaseSample/node_modules/native-base/lib/commonjs/utils/styled.js:18:5)
        at children (/Users/aclopesjr/git_repos/ReactNative/NativeBaseSample/node_modules/native-base/lib/commonjs/components/primitives/Pressable/Pressable.js:72:3)
        at children (/Users/aclopesjr/git_repos/ReactNative/NativeBaseSample/node_modules/native-base/lib/commonjs/components/primitives/Button/Button.js:38:3)
        at children (/Users/aclopesjr/git_repos/ReactNative/NativeBaseSample/node_modules/@react-aria/ssr/dist/SSRProvider.main.js:75:154)
        at children (/Users/aclopesjr/git_repos/ReactNative/NativeBaseSample/node_modules/native-base/lib/commonjs/components/composites/Toast/Toast.js:139:3)
        at useState (/Users/aclopesjr/git_repos/ReactNative/NativeBaseSample/node_modules/@react-native-aria/overlays/lib/commonjs/Portal.js:17:44)
        at children (/Users/aclopesjr/git_repos/ReactNative/NativeBaseSample/node_modules/native-base/lib/commonjs/core/hybrid-overlay/HybridProvider.js:23:3)
        at disableCSSMediaQueries (/Users/aclopesjr/git_repos/ReactNative/NativeBaseSample/node_modules/native-base/lib/commonjs/utils/useResponsiveQuery/ResponsiveQueryProvider.js:21:14)
        at RNCSafeAreaProvider
        at Component (/Users/aclopesjr/git_repos/ReactNative/NativeBaseSample/node_modules/react-native/jest/mockNativeComponent.js:17:18)
        at children (/Users/aclopesjr/git_repos/ReactNative/NativeBaseSample/node_modules/react-native-safe-area-context/lib/commonjs/SafeAreaContext.js:35:3)
        at children (/Users/aclopesjr/git_repos/ReactNative/NativeBaseSample/node_modules/native-base/lib/commonjs/utils/createContext.js:17:7)
        at colorModeManager (/Users/aclopesjr/git_repos/ReactNative/NativeBaseSample/node_modules/native-base/lib/commonjs/core/NativeBaseProvider.js:56:5)
        at RNCSafeAreaProvider
        at Component (/Users/aclopesjr/git_repos/ReactNative/NativeBaseSample/node_modules/react-native/jest/mockNativeComponent.js:17:18)
        at children (/Users/aclopesjr/git_repos/ReactNative/NativeBaseSample/node_modules/react-native-safe-area-context/lib/commonjs/SafeAreaContext.js:35:3)
        at children (/Users/aclopesjr/git_repos/ReactNative/NativeBaseSample/__tests__/App.test.tsx:16:19)
    
    Consider adding an error boundary to your tree to customize error handling behavior.
    Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.

      34 |
      35 |   it('Render NativeBase Button with react-test-renderer', () => {
    > 36 |     const component = renderer.create(
         |                                ^
      37 |       <Wrapper>
      38 |         <Button>Test</Button>
      39 |       </Wrapper>

      at logCapturedError (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:8678:23)
      at logCapturedError (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:8711:5)
      at call (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5175:12)
      at callCallback (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5196:9)
      at commitUpdateQueue (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:13271:13)
      at commitLayoutEffectOnFiber (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:14369:9)
      at commitLayoutMountEffects_complete (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:14355:7)
      at commitLayoutEffects_begin (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:14340:3)
      at commitLayoutEffects (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:16101:5)
      at commitRootImpl (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15972:5)
      at commitRoot (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15493:3)
      at callback (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22)
      at flushSyncCallbacks (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2576:5)
      at flushSyncCallbacksOnlyInLegacyMode (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:14949:7)
      at scheduleUpdateOnFiber (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:17809:5)
      at Object.updateContainer [as create] (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:18549:3)
      at Object.create (__tests__/App.test.tsx:36:32)

 FAIL  __tests__/App.test.tsx
  Snapshot Testing
    ✕ Render NativeBase Button with @testing-library/react-native (283 ms)
    ✕ Render NativeBase Button with react-test-renderer (15 ms)
    ✓ Render React Native Text with @testing-library/react-native (3 ms)
    ✓ Render React Native Text with react-test-renderer

  ● Snapshot Testing › Render NativeBase Button with @testing-library/react-native

    TypeError: Cannot read properties of undefined (reading 'width')

      25 |
      26 |   it('Render NativeBase Button with @testing-library/react-native', () => {
    > 27 |     render(
         |           ^
      28 |       <Wrapper>
      29 |         <Button>Test</Button>
      30 |       </Wrapper>

      at useResponsiveQuery (node_modules/native-base/lib/commonjs/utils/useResponsiveQuery/useResponsiveQuery.js:19:62)
      at useStyledSystemPropsResolver (node_modules/native-base/lib/commonjs/hooks/useStyledSystemPropsResolver.js:38:49)
      at node_modules/native-base/lib/commonjs/utils/styled.js:21:71
      at Component (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18)
      at renderWithHooks (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9169:20)
      at updateForwardRef (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11400:16)
      at beginWork$1 (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15850:12)
      at performUnitOfWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5)
      at workLoopSync (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7)
      at renderRootSync (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20)
      at callback (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22)
      at callback (node_modules/react/cjs/react.development.js:2667:24)
      at flushActQueue (node_modules/react/cjs/react.development.js:2521:11)
      at actImplementation (node_modules/@testing-library/react-native/build/act.js:31:25)
      at renderWithAct (node_modules/@testing-library/react-native/build/render-act.js:14:24)
      at renderInternal (node_modules/@testing-library/react-native/build/render.js:54:48)
      at renderInternal (node_modules/@testing-library/react-native/build/render.js:29:10)
      at Object.<anonymous> (__tests__/App.test.tsx:27:11)

  ● Snapshot Testing › Render NativeBase Button with react-test-renderer

    TypeError: Cannot read properties of undefined (reading 'width')

      34 |
      35 |   it('Render NativeBase Button with react-test-renderer', () => {
    > 36 |     const component = renderer.create(
         |                                ^
      37 |       <Wrapper>
      38 |         <Button>Test</Button>
      39 |       </Wrapper>

      at useResponsiveQuery (node_modules/native-base/lib/commonjs/utils/useResponsiveQuery/useResponsiveQuery.js:19:62)
      at useStyledSystemPropsResolver (node_modules/native-base/lib/commonjs/hooks/useStyledSystemPropsResolver.js:38:49)
      at node_modules/native-base/lib/commonjs/utils/styled.js:21:71
      at Component (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5608:18)
      at renderWithHooks (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9169:20)
      at updateForwardRef (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11400:16)
      at beginWork$1 (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15850:12)
      at performUnitOfWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15784:5)
      at workLoopSync (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15756:7)
      at renderRootSync (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15461:20)
      at callback (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22)
      at flushSyncCallbacks (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2576:5)
      at flushSyncCallbacksOnlyInLegacyMode (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:14949:7)
      at scheduleUpdateOnFiber (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:17809:5)
      at Object.updateContainer [as create] (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:18549:3)
      at Object.create (__tests__/App.test.tsx:36:32)

Test Suites: 1 failed, 1 total
Tests:       2 failed, 2 passed, 4 total
Snapshots:   2 passed, 2 total
Time:        2.949 s, estimated 3 s
Ran all test suites related to changed files.
@toninlopes
Copy link
Author

The jest.config.js file has the property setupFiles. So, for my surprise, when I remove that property, the test passed. And that made me think that the issue would be missing mock piece of code. So, I started to review the mocks and I found out the one was causing the issue.

Before

jest.mock('react-native/Libraries/Utilities/Dimensions', () => ({
  get: jest.fn(),
  set: jest.fn(),
  addEventListener: jest.fn(),
}));

After

jest.mock('react-native/Libraries/Utilities/Dimensions', () => ({
  get: jest.fn().mockImplementation(() => {
    return { width: 375, height: 812, scale: 0, fontScale: 0 };
  }),
  set: jest.fn(),
  addEventListener: jest.fn().mockImplementation(() => {
    return { remove: jest.fn() };
  }),
}));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant