I'm trying to render a component in jest and getting the following
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports. Check the render method of
SplashScreen
.
src/screens/Splash/Splash.tsx
import React from 'react'
import { View, Image } from 'react-native'
import { styleSplash } from './styles'
const SplashScreen = props => {
const {} = props
return (
<View style={styleSplash.main}>
<Image style={styleSplash.logo} source={require('../../img/logo.png')} />
</View>
)
}
export default SplashScreen
__tests__/Splash-test.tsx
import React from 'react';
import 'react-native';
import SplashScreen from '../src/screens/Splash/Splash';
import { render, waitFor } from '@testing-library/react-native';
it('renders correctly', async () => {
const tree = render(<SplashScreen />)
await waitFor(() => {
expect(tree).toMatchSnapshot();
});
});
I understand the difference between named and default exports, but as you can see, my code looks correct(?) so I've been super confused. If my path or import was incorrect, VS Code will also just throw me an error so that would be obvious. Am I just going insane or is there something wrong with the packages I'm using?
The versions (not really sure what would be relevant here):
"react": "18.2.0",
"@testing-library/jest-native": "^5.4.3",
"@testing-library/react": "^14.0.0",
"@testing-library/react-native": "11.5.1",
"@tsconfig/react-native": "^2.0.2",
"babel-jest": "^29.7.0",
"eslint": "^8.19.0",
"jest": "^29.7.0",
"jest-expo": "^49.0.0",
"metro-react-native-babel-preset": "0.73.9",
"react-dom": "^18.2.0",
"react-test-renderer": "18.2.0",
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */
which I couldn't fix. Seemed like using the testing-library was the more modern way to go, so I opted for that.
Various mixes of valid named exports, default exports, es6 syntax, and common js syntax. No change in the error message.
Tried using the latest version of @testing-library/react-native which gave me an error of
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
There seems to be an issue with your configuration that prevents React Native Testing Library from working correctly.
Please check if you are using compatible versions of React Native and React Native Testing Library.
Instead, so I tried downgrading it to 11.5.1
, which gave me the original error.
"transform": {
"^.+\\.tsx?$": "babel-jest"
}
to my jest config. No change in error message.
As you can see in my component, it used components from react-native
including View
and Image
. However, I had no jest mocks setup for these components, so the page was not being rendered.
I added
jest.mock('react-native', () => {
return {
View: () => {
return <>test</>;
},
Image: () => {
return <>test</>;
}
}
});
to my jest-setup file.
And my Splash-test.tsx.snap
file now shows
exports[`renders correctly 1`] = `"test"`;
which makes sense since all that gets rendered now is View
. Which is just <>test</>.