I am trying to test that the Button navigates to the right screen using react-native-testing library. I am using UI Kitten library for my components and facing the issues because of it. I am simply trying to render the Button in my test for now and getting the error: TypeError: Cannot read properties of undefined (reading 'name'). I am assuming that is the property that exists on the Icon that this button uses and I don't know how to mock / pass it. I wrapped my button in the ApplicationProvider because I was getting another error: TypeError: Cannot read properties of undefined (reading 'appearances'). Here is the code with the component I am trying to render and the test I am running:
// HomeBtn.tsx
import React from 'react';
import {Button} from '@ui-kitten/components';
import {HomeIcon} from '../shared/icons';
import styles from './Btn.style';
export const HomeBtn = ({navigation}: any) => {
return (
<Button
style={styles.button}
accessoryLeft={props => HomeIcon(props, styles.icon)}
onPress={() => navigation.navigate('Home')}
/>
);
};
//HomeIcon.tsx
import React from 'react';
import {Icon} from '@ui-kitten/components';
const HomeIcon = (props: any = {}, styles: any = {}) => (
<Icon style={styles} fill="#000" name="home" {...props} />
);
export default HomeIcon;
//HomeBtn.test.tsx
import React from 'react';
import * as eva from '@eva-design/eva';
import {ApplicationProvider} from '@ui-kitten/components';
import {render} from '@testing-library/react-native';
import {HomeBtn} from '../../../components/buttons/HomeBtn';
describe('HomeBtn', () => {
it('should navigate to the Home Screen', () => {
const pushMock = jest.fn();
render(
<ApplicationProvider {...eva} theme={eva.light}>
<HomeBtn navigation={{ push: pushMock }} />
</ApplicationProvider>,
);
expect(pushMock).toBeCalledWith('Home');
});
});
That's the right way to render the components if you use ui-kitten library:
// HomeBtn.tsx
import React from 'react';
import {Button} from '@ui-kitten/components';
import {HomeIcon} from '../shared/icons';
import styles from './Btn.style';
export const HomeBtn = ({navigation}: any) => {
return (
<Button
style={styles.button}
accessoryLeft={props => HomeIcon(props, styles.icon)}
onPress={() => navigation.navigate('Home')}
/>
);
};
//HomeIcon.tsx
import React from 'react';
import {Icon} from '@ui-kitten/components';
const HomeIcon = (props: any = {}, styles: any = {}) => (
<Icon style={styles} fill="#000" name="home" {...props} />
);
export default HomeIcon;
//HomeBtn.test.tsx
import React from 'react';
import * as eva from '@eva-design/eva';
import {RootSiblingParent} from 'react-native-root-siblings';
import {EvaIconsPack} from '@ui-kitten/eva-icons';
import {ApplicationProvider} from '@ui-kitten/components';
import {render} from '@testing-library/react-native';
import {HomeBtn} from '../../../components/buttons/HomeBtn';
describe('HomeBtn', () => {
it('should navigate to the Home Screen', () => {
const pushMock = jest.fn();
const {getByTestId} = render(
<RootSiblingParent>
<IconRegistry icons={EvaIconsPack} />
<ApplicationProvider {...eva} theme={eva.light}>
<HomeBtn navigation={{push: pushMock}} />
</ApplicationProvider>
</RootSiblingParent>,
);
fireEvent.press(getByTestId('homeBtn'));
expect(pushMock).toBeCalledWith('Home');
});
});