Testing the ui-kitten button with react native testing library

646 Views Asked by At

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');
  });
});

1

There are 1 best solutions below

0
dnd1993 On BEST ANSWER

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');
  });
});