React Native Environment Info:
System:
OS: macOS 10.14.1
CPU: (8) x64 Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
Memory: 496.23 MB / 16.00 GB
Shell: 5.3 - /bin/zsh
Binaries:
Node: 8.11.2 - /usr/local/bin/node
Yarn: 1.6.0 - ~/.yarn/bin/yarn
npm: 5.6.0 - /usr/local/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
SDKs:
iOS SDK:
Platforms: iOS 12.1, macOS 10.14, tvOS 12.1, watchOS 5.1
Android SDK:
API Levels: 21, 22, 23, 24, 25, 26, 27, 28
Build Tools: 23.0.1, 24.0.1, 25.0.1, 25.0.2, 25.0.3, 26.0.0, 26.0.1, 26.0.2, 27.0.3, 28.0.2, 28.0.3
System Images: android-22 | Google APIs Intel x86 Atom, android-24 | Google APIs Intel x86 Atom
IDEs:
Android Studio: 3.2 AI-181.5540.7.32.5056338
Xcode: 10.1/10B61 - /usr/bin/xcodebuild
npmPackages:
react: ^16.6.3 => 16.6.3
react-native: ^0.57.5 => 0.57.5
npmGlobalPackages:
create-react-native-app: 1.0.0
react-native-cli: 2.0.1
react-native: 0.57.5
Additionally I`m using these babel packages:
"@babel/cli": "^7.1.5",
"@babel/core": "^7.1.6",
"@babel/plugin-proposal-class-properties": "^7.1.0",
"@babel/preset-env": "^7.1.6",
"@babel/runtime": "^7.1.5",
"babel-jest": "^23.6.0",
"babel-plugin-jest-hoist": "^23.2.0",
When I import a component like the example below:
export default class ButtonHold extends React.PureComponent<Props> {
state = {
locked: true,
unlocking: false,
buttonWidth: 0
}
....
}
the test produces the following error:
FAIL src/components/button-hold.test.js
<ButtonHold>
Structure
✕ renders correctly (6ms)
● <ButtonHold> › Structure › renders correctly
TypeError: Cannot read property 'default' of undefined
14 | }
15 |
> 16 | export default class ButtonHold extends React.PureComponent<Props> {
| ^
17 | static defaultProps = {
18 | style: undefined,
19 | description: undefined
at new ButtonHold (src/components/button-hold.js:16:423)
at ReactShallowRenderer.render (node_modules/react-test-renderer/cjs/react-test-renderer-shallow.development.js:398:26)
at node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:480:35
at withSetStateAllowed (node_modules/enzyme-adapter-utils/build/Utils.js:137:16)
at Object.render (node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:479:68)
at new ShallowWrapper (node_modules/enzyme/build/ShallowWrapper.js:204:22)
at shallow (node_modules/enzyme/build/shallow.js:21:10)
at Object.<anonymous> (src/components/button-hold.test.js:11:41)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: 2.242s
This only happens when the state is defined as class property, when I define it inside the constructor, the test runs normally
Could you post a minimal reproduction? 1 component, 1 test, keep adding your specific details until it's reproducible. It is hard to help you without more context.
Sure, here it goes
The test:
import React from 'react'
import { shallow } from 'enzyme'
import ComponentTest from './component'
describe('<Component>', () => {
const sampleText = 'test'
const Component = <ComponentTest title={sampleText} />
describe('Structure', () => {
it('renders correctly', () => {
const wrapper = shallow(Component)
expect(wrapper).toMatchSnapshot()
})
})
})
the component with state defined inside constructor, working :
import React, { PureComponent } from 'react'
import { View, Text } from 'react-native'
type Props = {
title: string
}
export default class TestComponent extends PureComponent<Props> {
constructor() {
super()
this.state = {
show: true
}
}
render() {
return (
<View>
{this.state.show && <Text>{this.props.title}</Text>}
</View>
)
}
}
The test result for the above example:
$ node node_modules/jest/bin/jest.js
PASS src/components/component.test.js
› 1 snapshot written.
The component with state class property :
import React, { PureComponent } from 'react'
import { View, Text } from 'react-native'
type Props = {
title: string
}
export default class TestComponent extends PureComponent<Props> {
state = {
show: true
}
render() {
return (
<View>
{this.state.show && <Text>{this.props.title}</Text>}
</View>
)
}
}
The test result for the above example:
FAIL src/components/component.test.js
● <Component> › Structure › renders correctly
TypeError: Cannot read property 'default' of undefined
5 | title: string
6 | }
> 7 | export default class TestComponent extends PureComponent<Props> {
| ^
8 | state = {
9 | show: true
10 | }
at new TestComponent (src/components/component.js:7:419)
at ReactShallowRenderer.render (node_modules/react-test-renderer/cjs/react-test-renderer-shallow.development.js:398:26)
at node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:480:35
at withSetStateAllowed (node_modules/enzyme-adapter-utils/build/Utils.js:137:16)
at Object.render (node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:479:68)
at new ShallowWrapper (node_modules/enzyme/build/ShallowWrapper.js:204:22)
at shallow (node_modules/enzyme/build/shallow.js:21:10)
at Object.<anonymous> (src/components/component.test.js:11:41)
Thanks for the help
@KalebPortillo
Additionally it's better to post jest config from reproduce exmple's package.json or jest.config.js.
If you use jest/preprocessor.js as transformer, #22175 would be helpful.
Jest config file:
import { configure } from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
configure({ adapter: new Adapter() })
packege.json
{
"name": "mora",
"version": "0.0.1",
"private": true,
"scripts": {
....
},
"dependencies": {
"apisauce": "^1.0.0",
"react": "^16.6.3",
"react-native": "^0.57.5",
"react-native-config": "^0.11.5",
"react-native-fast-image": "^5.1.1",
"react-native-firebase": "^5.0.0",
"react-native-google-signin": "^1.0.1",
"react-native-splash-screen": "^3.0.6",
"react-navigation": "^2.18.1",
"react-navigation-redux-helpers": "^2.0.8",
"react-redux": "^5.0.7",
"redux": "^3.7.2",
"redux-logger": "^3.0.6",
"redux-persist": "^5.9.1",
"redux-thunk": "^2.2.0",
"reselect": "^3.0.1"
},
"devDependencies": {
"@babel/cli": "^7.1.5",
"@babel/core": "^7.1.6",
"@babel/plugin-proposal-class-properties": "^7.1.0",
"@babel/preset-env": "^7.1.6",
"@babel/runtime": "^7.1.5",
"babel-eslint": "^10.0.1",
"babel-jest": "^23.6.0",
"babel-plugin-jest-hoist": "^23.2.0",
"enzyme": "^3.7.0",
"enzyme-adapter-react-16": "^1.7.0",
"enzyme-to-json": "^3.3.4",
"eslint": "^5.9.0",
"eslint-config-airbnb": "^17.1.0",
"eslint-config-prettier": "^3.3.0",
"eslint-plugin-flowtype": "^3.2.0",
"eslint-plugin-import": "^2.14.0",
"eslint-plugin-jsx-a11y": "^6.1.2",
"eslint-plugin-react": "^7.11.1",
"fs-extra": "^6.0.1",
"husky": "^1.2.0",
"jest": "23.6.0",
"lint-staged": "^8.1.0",
"metro-react-native-babel-preset": "^0.49.2",
"prettier": "^1.15.2",
"react-dom": "^16.6.3",
"react-test-renderer": "^16.6.1",
"replace-in-file": "^3.4.0",
"schedule": "0.4.0"
},
"jest": {
"preset": "react-native",
"transform": {
"^.+\\.js$": "<rootDir>/node_modules/react-native/jest/preprocessor.js"
},
"testMatch": [
"**/?(*.)test.js?(x)"
],
"snapshotSerializers": [
"enzyme-to-json/serializer"
],
"setupFiles": [
"<rootDir>/jest/setup.js"
]
},
"lint-staged": {
"*.js": [
"yarn pretty",
"git add"
]
},
"husky": {
"hooks": {
"pre-commit": "lint-staged && yarn test",
"pre-push": "lint-staged && yarn test"
}
},
"rnpm": {
"assets": [
"./src/assets/fonts/"
]
},
"babel": {
"presets": [
"module:metro-react-native-babel-preset"
],
"plugins": [
"@babel/plugin-proposal-class-properties",
"jest-hoist"
]
}
}
Same issue. If the component has a class property, e.g.:
export class MyComponent extends Component {
state = {
showButtons: true
}
...
getting the error TypeError: Cannot read property 'default' of undefined when running a jest test.
I've got the same problem on React Native 0.57.7.
It's strange because the Jest preprocessor <rootDir>/node_modules/react-native/jest/preprocessor.js explicitly uses the @babel/plugin-proposal-class-properties plugin if you inspect its code:
plugins: [
[require('@babel/plugin-transform-block-scoping')],
// the flow strip types plugin must go BEFORE class properties!
// there'll be a test case that fails if you don't.
[require('@babel/plugin-transform-flow-strip-types')],
[
require('@babel/plugin-proposal-class-properties'),
// use `this.foo = bar` instead of `this.defineProperty('foo', ...)`
{loose: true},
],
...
Any workarounds?
@KalebPortillo
Thanks for your post.
I reproduced https://github.com/facebook/react-native/issues/22437#issuecomment-442480938.
The workaround is https://github.com/facebook/react-native/issues/22175#issuecomment-439988478.
I confirmed the reproduced test passed fine when using this workaround.
Hey @sasurau4 , it worked!
Thanks for the help!
Just for someone that may endup here in this issue, the workaround consists in:
preprocessor.js file inside react-native jest folder, normally located in this path <rootDir>/node_modules/react-native/jest/preprocessor.js and inlineRequires: true to inlineRequires: false This should obviously be fixed but closing this issue as a duplicate of #22175 to concentrate info there
@kelset close
Most helpful comment
Hey @sasurau4 , it worked!
Thanks for the help!
Just for someone that may endup here in this issue, the workaround consists in:
preprocessor.jsfile inside react-native jest folder, normally located in this path<rootDir>/node_modules/react-native/jest/preprocessor.jsandinlineRequires: truetoinlineRequires: false