'How to replace a React component with a mock when testing with Jest
I am really stuck on this in the project I am working on, and all the answers I have found seem to be so simple but they haven't worked for me. Perhaps I don't really understand what a mock is, and I could really use some guidance.
I am testing a parent component that has a child component that fetches some data from a database using GraphQL. While testing the parent, I do not care what the child is doing. I want to replace the child with a mocked component (one that doesn't fetch data from a database) so that I can only focus on the parent.
I have come up with the simplest example possible to show my situation. Note that I'm using React Native and React Native Testing Library.
./src/ParentComponent.js
import React from 'react';
import { Text, View } from 'react-native';
import ChildComponent from './ChildComponent';
const ParentComponent = () => (
<View>
<Text>Hello World</Text>
<ChildComponent />
</View>
);
export default ParentComponent;
./src/ChildComponent.js
import React from 'react';
import { useQuery } from 'react-apollo';
import { View, Text } from 'react-native';
import gql from 'graphql-tag';
const CURRENT_USER_QUERY = gql`
query {
currentUser {
username
}
}
`;
const ChildComponent = () => {
const { data } = useQuery(CURRENT_USER_QUERY);
const { username } = data.currentUser;
return (
<View>
<Text>Welcome, {username}</Text>
</View>
);
};
export default ChildComponent;
./src/__mocks__/ChildComponent.js
import React from 'react';
import { Text } from 'react-native';
const ChildComponent = () => <Text>Welcome.</Text>;
export default ChildComponent;
./src/ParentComponent.test.js
import React from 'react';
import { MockedProvider } from '@apollo/react-testing';
import { render } from '@testing-library/react-native';
import ParentComponent from '../ParentComponent';
it(`should render the parent component.`, () => {
jest.mock('../ChildComponent');
const { getByText } = render(
<MockedProvider>
<ParentComponent />
</MockedProvider>
);
expect(getByText('Hello World')).toBeTruthy();
});
When I run the test, I get the following error...
● should render the parent component.
TypeError: Cannot read property 'currentUser' of undefined
14 | const ChildComponent = () => {
15 | const { data } = useQuery(CURRENT_USER_QUERY);
> 16 | const { username } = data.currentUser;
| ^
17 |
18 | return (
19 | <View>
at ChildComponent (src/ChildComponent.js:16:29)
It is still using the real <ChildComponent />. Why is it not replacing the <ChildComponent /> with the mocked version in the __mocks__ directory? Is that not how mocks work? If someone can please help and explain, it would be much appreciated. Thank you.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
