Open mahdieh-dev opened 2 years ago
For those who need a solution to this problem:
I ended up mocking the reanimated
package like this:
jest.mock('react-native-reanimated', () => {
return {
...jest.requireMock('react-native-reanimated/mock'),
useSharedValue: jest.fn,
useAnimatedStyle: jest.fn,
useAnimatedRef: () => ({ current: null }),
default: {
...jest.requireMock('react-native-reanimated/mock').default,
createAnimatedComponent: (Component) => Component,
},
};
});
This solves the issue with Animated components, and also some features related to reanimated V2
Update:
Actually, the problem was with the requireMock
, it works with requireActual
.
Changing the mock to:
jest.mock('react-native-reanimated', () => {
return {
...jest.requireActual('react-native-reanimated/mock'),
...jest.requireActual('react-native-reanimated/src/reanimated2/mock'),
};
});
solves the problem.
For those who need a solution to this problem: I ended up mocking the
reanimated
package like this:jest.mock('react-native-reanimated', () => { return { ...jest.requireMock('react-native-reanimated/mock'), useSharedValue: jest.fn, useAnimatedStyle: jest.fn, useAnimatedRef: () => ({ current: null }), default: { ...jest.requireMock('react-native-reanimated/mock').default, createAnimatedComponent: (Component) => Component, }, }; });
This solves the issue with Animated components, and also some features related to reanimated V2
Update:
Actually, the problem was with the
requireMock
, it works withrequireActual
. Changing the mock to:jest.mock('react-native-reanimated', () => { return { ...jest.requireActual('react-native-reanimated/mock'), ...jest.requireActual('react-native-reanimated/src/reanimated2/mock'), }; });
solves the problem.
I have the same problem, but this mock doesn't work for me.
Invariant Violation:
createAnimatedComponent` does not support stateless functional components; use a class component instead.
46 | }
47 |
> 48 | const AnimatedColumn = Animated.createAnimatedComponent(Column);
| ^
49 | const defaultAnimationDuration = 0;
50 |
51 | const Overlay: ForwardRefRenderFunction<OverlayRef, OverlayProps> = (
at invariant (node_modules/invariant/invariant.js:40:15)
at Object.createAnimatedComponent (node_modules/react-native/Libraries/Animated/src/createAnimatedComponent.js:28:3)`
i`m tryng testing with a styled component library, maybe my error is because styled components doesnt works with animated components, but idk.
@Michelalmeidasilva You can use styled-components
using a dumb class component for that:
class ColumnKlass extends React.Component {
render() {
return <Column />; //Styled component
}
}
const AnimatedColumn = Animated.createAnimatedComponent(ColumnKlass);
Btw seems that some mocks are missing for the Layout
components (on both reanimated
and reanimated2
mocks). You can solve that issue by mocking the missing stuff yourself 😄
jest.mock('react-native-reanimated', () => {
const Reanimated = require('react-native-reanimated/mock');
// The mock for `call` immediately calls the callback which is incorrect
// So we override it with a no-op
Reanimated.default.call = () => {};
const DefaultLayoutAnimation: unknown = {
delay: (_: number) => DefaultLayoutAnimation,
duration: (_: number) => DefaultLayoutAnimation,
withCallback: () => DefaultLayoutAnimation,
withInitialValues: (_: unknown) => DefaultLayoutAnimation,
randomDelay: (_: number) => DefaultLayoutAnimation,
};
return {
...Reanimated,
FadeIn: DefaultLayoutAnimation,
BounceIn: DefaultLayoutAnimation,
};
});
NOTE: In my case I'm only using FadeIn
and BounceIn
default animations so I only mocked those two
I am encountering an issue
where I want the withCallback
to be called but
even if I remove the line with that Reanimated.default.call
its still not being called
"react-native-reanimated": "^2.14.4",
component
const [openState, setOpenState] = useState(true);
const onWillClose = () => {
setOpenState(false);
};
const onExit = (finished: boolean) => {
'worklet';
console.log('on exit');
if (finished) {
runOnJS(onCloseModal)();
}
};
const onShown = (finished: boolean) => {
'worklet';
console.log('on open');
if (finished && onModalShown) {
runOnJS(onModalShown)();
}
};
return (
<ReAnimated.View {...testProps(testID)} style={styles.main}>
{openState && (
<>
<ReAnimated.View
style={styles.background}
entering={FadeIn}
exiting={FadeOut}
/>
<ReAnimated.View
style={styles.containerStyle}
entering={SlideInDown.withCallback(onShown)}
exiting={SlideOutDown.withCallback(onExit)}
>
<Pressable
{...testProps(testID + '.pressable')}
style={styles.pressable}
onPress={onWillClose}
/>
<View style={styles.contents}>
{children}
<SafeAreaView edges={['bottom']} />
</View>
</ReAnimated.View>
</>
)}
</ReAnimated.View>
);
test
jest.mock('react-native-reanimated', () => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const Reanimated = require('react-native-reanimated/mock');
// The mock for `call` immediately calls the callback which is incorrect
// So we override it with a no-op
//Reanimated.default.call = () => {};
const DefaultLayoutAnimation: unknown = {
delay: (_: number) => DefaultLayoutAnimation,
duration: (_: number) => DefaultLayoutAnimation,
withCallback: () => DefaultLayoutAnimation,
withInitialValues: (_: unknown) => DefaultLayoutAnimation,
randomDelay: (_: number) => DefaultLayoutAnimation,
};
return {
...Reanimated,
SlideInDown: DefaultLayoutAnimation,
SlideOutDown: DefaultLayoutAnimation,
};
});
it('invokes open', () => {
render(
<Component
testID="sample"
onCloseModal={mockOnClose}
onModalShown={mockOnOpen}
>
<Text>Sample Text</Text>
<Button title="Sample Button" />
</Component>,
);
expect(mockOnOpen).toHaveBeenCalled();
});
Hey! 👋
The issue doesn't seem to contain a minimal reproduction.
Could you provide a snack or a link to a GitHub repository under your username that reproduces the problem?
Description
I have a screen that contains an animated
FlatList
and I need to useref
for it, so I created my Animated list like below:I need to test an element in this list is working fine, however, I cannot get the test running. Because it fails on my
AnimatedList
component with the following error:I have mocked the
react-native-reanimated
component like this:So I tried to log what is really inside my
AnimatedList
and gotundefined
. I tried to logAnimated.createAnimatedComponent
itself since I knew it exists in the package mock, and this is what is logged in the console:But when I log
Animated.createAnimatedComponent(FlatList)
it returnsundefined
. I tried to mock this function after the line...jest.requireMock('react-native-reanimated/mock'),
like(Component) => Component
but it didn't work. So I tried to remove this line...jest.requireMock('react-native-reanimated/mock'),
and try to mock the required components and functions myself. This time it worked and in the logs, I could see that the component is returned by theAnimated.createAnimatedComponent(FlatList)
, however, the test failed again, because other reanimated components were not mocked correctly. So I believe the issue should be inside the mock file, I couldn't figure out what is the reason it is not returningundefined
instead of the component. I would be grateful if you help me fix this issue, it took me 2 days but has not been resolved yet.Steps to reproduce
npm i
to install the dependenciesnpx jest
(it will fail on AnimatedList component and I provided the logs I described above which you can check on the console)Snack or a link to a repository
https://github.com/mshavandi/reanimatedMockIssueWithJest
Reanimated version
3.0.0-rc.1
React Native version
0.68.2
Platforms
Android
JavaScript runtime
No response
Workflow
No response
Architecture
No response
Build type
No response
Device
No response
Device model
No response
Acknowledgements
Yes