I just added TouchableOpacity
to a component and the app is working fine, but my tests, using react-native-testing-library
, fail to run:
● Test suite failed to run
TypeError: Cannot read property 'Direction' of undefined
at Object.Direction (node_modules/react-native-gesture-handler/Directions.js:3:39)
at Object.<anonymous> (node_modules/react-native-gesture-handler/GestureHandler.js:2:1)
I just removed and re-added react-native-gesture-handler
with yarn, and ran pod install
. Again, the app is working, but the tests fail to run.
I actually get the same error when using <Text onPress={() => onOptionPress(opt)} />
rather than TouchableOpacity
.
component:
const SelectOptions = ({ field, dismissOverlay, onOptionPress }) => {
return (
<Overlay
isVisible
overlayStyle={styles.overlay}
height={"auto"}
onBackdropPress={dismissOverlay}
>
<View>
{field.options.map((opt, i) => (
<TouchableOpacity
style={styles.option}
key={i}
onPress={() => onOptionPress(opt)}
>
<Text>{opt}</Text>
</TouchableOpacity>
))}
</View>
</Overlay>
);
};
test:
describe("CardFormView", () => {
let wrapper, birthdayField;
beforeEach(() => {
wrapper = render(
<React.Fragment>
<CardFormView form={form} />
</React.Fragment>
);
birthdayField = wrapper.getByText("Add a Birthday Gift Card");
});
const message1 =
"...";
const message2 =
"...";
it("shows the options for a birthday card when clicked", () => {
fireEvent.press(birthdayField);
expect(wrapper.getByText(message1)).toBeDefined();
});
it("sets an option when clicked", () => {
fireEvent.press(birthdayField);
const firstOption = wrapper.getByText(message1);
fireEvent.press(firstOption);
expect(wrapper.queryByText(message2)).toBeNull();
expect(wrapper.getByText(message1)).toBeDefined();
});
});
This is because you are not mocking the react-navigation-gesture-handler
To use mock of react-navigation-gesture-handler
you should add jestSetup.js from node_modules in jest.config.json or jest.config.js
setupFiles: [
"./node_modules/react-native-gesture-handler/jestSetup.js"
]
I found a reference from the following link and It's working for me.
https://github.com/software-mansion/react-native-gesture-handler/issues/344#issuecomment-489547513
For me just adding the setupFiles didn't work. I added setupFiles and transformIgnorePatterns at "jest" in package.json
Here the code to make the gestureHandler work, but I tested it with AsyncStorage and the storage stopped work. If you aren't using AsyncStorage I presume this code will work very well!
"setupFiles": [
"./node_modules/react-native-gesture-handler/jestSetup.js"
],
"transformIgnorePatterns": [
"/node_modules/(?!native-base)/"
]
My reference: https://github.com/software-mansion/react-native-gesture-handler/issues/344
Updating package.json and reinstalling npm package worked for me.
"jest": {
"preset": "react-native",
"transformIgnorePatterns": ["node_modules/(?!(jest-)?react-native|@?react-navigation)"],
"setupFiles": ["./node_modules/react-native-gesture-handler/jestSetup.js"]
}
This is happening because you have to mock the NativeModules
module from react-native. It can happen with several modules but it was happening to me specifically with the ImagePicker
, Linking
and @react-navigation/native
. This is what I did to mock the native modules.
/src/testSetup.ts
import {NativeModules} from 'react-native';
NativeModules.RNGestureHandlerModule= {
attachGestureHandler: jest.fn(),
createGestureHandler: jest.fn(),
dropGestureHandler: jest.fn(),
updateGestureHandler: jest.fn(),
State: {},
Directions: {},
},
NativeModules.ImagePickerManager = {
showImagePicker: jest.fn(),
}
NativeModules.Linking = {
canOpenUrl: jest.fn().mockResolvedValue(true),
openUrl: jest.fn().mockResolvedValue(true)
}
NativeModules.Platform = {
OS: 'iOS'
}
jest.mock('react-native/Libraries/Animated/src/NativeAnimatedHelper');
jest.mock('react-native/Libraries/Animated/src/animations/TimingAnimation');
const mockNavigation = () => {
const mockedNavigate = jest.fn();
const mockedAddListener = jest.fn();
jest.mock('@react-navigation/native', () => ({ // @ts-ignore
...(jest.requireActual('@react-navigation/native')),
useNavigation: () => ({
navigate: mockedNavigate,
addListener: mockedAddListener
})
}));
return {mockedNavigate, mockedAddListener}
}
in your tests
import { fireEvent, act, render } = '@testing-library/react-native'
const {mockedNavigate, mockedAddListener} = mockNavigation()
test('Should navigate', () => {
const { queryByText } = render(<Component />)
fireEvent.press(getByText('View Page Button'))
expect(mockedNavigate).toHaveBeenCalledWith('Your Page Name')
expect(mockedAddListener).toHaveBeenCalled()
})
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