react-native-testing-library: fireEvent seems to always trigger event (on disabled TouchableOpacity)
I’m trying to figure out why it seems like the fireEvent.press
function always seem to trigger a callback even though it shouldn’t be registered. My use case is that I’m trying to write a test that makes sure that onPress
isn’t called if the component is “disabled”.
Trying to mimic the behaviour below…
const MyComponent = _props => (
<View>
<TouchableHighlight testID={'touchable'}>
<Text>{'Foo'}</Text>
</TouchableHighlight>
</View>
)
const pressedCallback = jest.fn()
const { getByTestId } = render(<MyComponent onPress={() => pressedCallback('bar')} />)
fireEvent.press(getByTestId('touchable'))
expect(pressedCallback).not.toBeCalled() //Expected mock function not to be called but it was called with: ["bar"]
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 8
- Comments: 30 (15 by maintainers)
could it be this bug is back again? Because Im testing with the extended version that is disabled like this:
expect(something).toBeDisabled();
and this passes correctly but then I do this:
and this fails saying it was called 1 time 😢
Im using
"@testing-library/react-native": "^9.1.0"
For example this works:
But then again I’m changing implementation to satisfy the test 😅
@TDAK1509 I encourage you to use https://github.com/jest-community/snapshot-diff in such cases 😃
Yup, we have an idea on how to make it more generic without changing implementation of
fireEvent
. Bare with us while we’re fixing this.@alexakasanjeev we’re not currently working on this. But the proper place to fix it is the
Touchable*
components in RN core. I won’t patch the library to work around specific logic that lives on the native side.For example, there’s a new
Pressable
component coming up, which may or may not have this issue. Shall we patch it then as well? What about other components? I hope you see my point. This is an upstream “bug” (or limitation) and I only leave it open for folks to be aware.I can only advise to always wrap RN touchable components into custom components which you can control. This will also make touchables unified across your app, so it’s worth doing anyway. A sample implementation: https://github.com/react-native-community/react-native-platform-touchable/blob/master/PlatformTouchable.js of such primitive
We also just came across this issues. I have added a mock in the
setup.js
to keep it tucked away and ignore moving forward 🙄I test the disable status by using snapshot to check the style. (When disabled, my button has a different color)
After doing this, in snapshot file there will be 2 cases for the button, which will be disabled state and enabled state with different colors.
I’d extract
disabled
to a variable since it’s reused, but yes.For test purposes you’ll need to make sure by yourself that your events won’t fire when disabled prop is passed, there’s not really other way until the mocks are fixed.
We may, however, consider some special treatment for
Touchable*
components when in RN context (usual), as these are special and e.g. cancel-out event bubbling, unlike one the web where events propagate up freely unless stopped explicitly by the user.Just merged #30 so the bug is fixed now (not released yet). As for
disabled
prop, this is something that should be fixed in RN mocks tbh. We’ll need to think about simulating native events capturing as close as possible though (e.g. including capturing phase).I think it makes sense to stop bubbling just before root component, that would prevent this and seems like a sane solution, but haven’t thought it through yet