I have implemented the component below, which is a card containing information about a product and a button that, when pressed, redirects the user to the details screen.
export default function ProductItem(props: ProductItemProps) {
const {navigate} = useNavigation<any>();
const {title, id, rating, category, price, thumbnail} = props;
function navigateToProduct() {
navigate('Product', {id, title});
}
return (
<TouchableOpacity
testID="button-nav"
style={styles.container}
activeOpacity={0.75}
onPress={navigateToProduct}>
<Image source={{uri: thumbnail, width: 100, height: 100}} />
<View style={styles.contentInfo}>
<Text style={styles.title}>{title}</Text>
<Text>{category}</Text>
<StarRating rating={rating} />
<Text style={styles.price}>R${price}</Text>
</View>
</TouchableOpacity>
);
}
So far, I've already implemented the test to check the component's rendering, but I need to test if when the button is pressed, the "navigateToProduct" function will be executed.
import {fireEvent, render, screen} from '@testing-library/react-native';
import ProductItem from '..';
describe('<ProductItem/>', () => {
const product = {
title: 'title-test',
id: 1,
rating: 4.5,
category: 'category-test',
price: 499,
thumbnail: 'thumbnail-test',
description: 'description-test',
stock: 1,
brand: 'brand-test',
images: ['image1-test', 'image2-test'],
};
it('Should render correctly product item component', () => {
render(<ProductItem {...product} />);
const title = screen.getByText(product.title);
expect(title).toBeTruthy();
});
it('Should navigate to product screen when button pressed', async () => {
render(<ProductItem {...product} />);
const toPress = screen.getByTestId('button-nav');
fireEvent.press(toPress);
});
});
The whole mock of react navigation "useNavigation" already works. And until then, the tests are all passing. My question is just how can I test if the function is executed. I've tried using spyOn, but I don't know exactly how I can mock this function within my tests. Can anyone give me any suggestions?
You can create a mock function with jest.fn()
and use expect(mockFn).toBeCalled()
after firing the key press even to test if the function has been called. Here is an example from the React Native Testing Library docs (swap toBeCalledWith
and toBeCalled
for your use case):
test('form submits two answers', () => {
const allQuestions = ['q1', 'q2'];
const mockFn = jest.fn();
render(<QuestionsBoard questions={allQuestions} onSubmit={mockFn} />);
const answerInputs = screen.getAllByLabelText('answer input');
fireEvent.changeText(answerInputs[0], 'a1');
fireEvent.changeText(answerInputs[1], 'a2');
fireEvent.press(screen.getByText('Submit'));
expect(mockFn).toBeCalledWith({
1: { q: 'q1', a: 'a1' },
2: { q: 'q2', a: 'a2' },
});
});