I have set up a really, really simple component in react native using typescript. My goal is just to get Jest set up and a simple test to pass. Here is the code for App.tsx:
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
export default function App() {
return (
<View style={styles.container}>
<Text>Hello World!</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
and the test:
import React from 'react';
import App from '../App';
import { create } from "react-test-renderer";
test('renders correctly', () => {
const tree = create(<App />);
expect(tree.toJSON()).toMatchSnapshot();
});
'Hello World' renders as expected but when I run the test I get:
console.error
Warning: React.createElement: type is invalid -- expected a string (for built-in componen
ts) or a class/function (for composite components) but got: object.
And indeed when I check the exported function 'App's type it is a React.Element not a component. But why is that? It is returning an element but I thought thats what a component was supposed to do. The export itself is a stateless function so I am a bit confused...
UPDATE: Dennis Tsoi added
"moduleFileExtensions": [
"ts",
"tsx",
"js"
],
to the 'jest' object in package.json and that fixed the typerror. It seems expo client does not create everything needed to run tpyescript in react native
Jest supports TypeScript, via Babel. First, make sure you followed the instructions on using Babel above. Next, install the @babel/preset-typescript : npm.
The Jest preset built into react-native comes with a few default mocks that are applied on a react-native repository. However, some react-native components or third party components rely on native code to be rendered. In such cases, Jest's manual mocking system can help to mock out the underlying implementation.
When you run jest with a jest. config. ts file it will use ts-node to compile that file, then it will pass it to ts-jest which will compile your tests, then it will pass those . js tests to jest to run it.
Edit:
From looking at the remote repository, https://github.com/adamglang/rnTranslatedBible
The error was related a missing jest configuration in the package.json.
Note:
Solution:
package.json
"jest": {
"preset": "react-native",
"moduleFileExtensions": [
"ts",
"tsx",
"js"
]
},
According to the jest docs, the default configuration is:
Default: ["js", "json", "jsx", "ts", "tsx", "node"]
By altering the order, whereby "ts"
and "tsx"
are moved infront of js
, the issue is resolved.
Suggest react-native-testing-library as react-test-renderer can have some issues with react native;
Note: requires react-native-testing-library as a devDependancy.
Commentary:
You want to write maintainable tests for your React Native components without testing implementation details, but then you're told to use Enzyme, which you learn has no React Native adapter, meaning only shallow rendering is supported. And you want to render deep! But deep rendering may otherwise require jsdom (React Native isn't the web!), while doing deep rendering with react-test-renderer is so painful.
App.tsx
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
export default function App() {
return (
<View style={styles.container}>
<Text>Hello World!</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
test.ts
import React from "react";
import { render } from "react-native-testing-library";
import App from "../App";
describe("App", () => {
it("App", async () => {
const component = render(<App />);
expect(component.toJSON()).toMatchSnapshot();
});
});
Edit [Attach snapshot]
exports[`App App 1`] = `
<View
style={
Object {
"alignItems": "center",
"backgroundColor": "#fff",
"flex": 1,
"justifyContent": "center",
}
}
>
<Text>
Hello World!
</Text>
</View>
`;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With