react-native-reanimated
react-native-reanimated copied to clipboard
Animated.createAnimatedComponent mock returns undefined instead of the Component when running jest
Description
I have a screen that contains an animated FlatList
and I need to use ref
for it, so I created my Animated list like below:
const AnimatedList = Animated.createAnimatedComponent(FlatList)
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:
console.error
Warning: React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
I have mocked the react-native-reanimated
component like this:
jest.mock('react-native-reanimated', () => {
return {
...jest.requireMock('react-native-reanimated/mock'),
useSharedValue: jest.fn,
useAnimatedStyle: jest.fn,
};
});
So I tried to log what is really inside my AnimatedList
and got undefined
.
I tried to log Animated.createAnimatedComponent
itself since I knew it exists in the package mock, and this is what is logged in the console:
[Function: createAnimatedComponent] {
_isMockFunction: true,
getMockImplementation: [Function (anonymous)],
mock: [Getter/Setter],
mockClear: [Function (anonymous)],
mockReset: [Function (anonymous)],
mockRestore: [Function (anonymous)],
mockReturnValueOnce: [Function (anonymous)],
mockResolvedValueOnce: [Function (anonymous)],
mockRejectedValueOnce: [Function (anonymous)],
mockReturnValue: [Function (anonymous)],
mockResolvedValue: [Function (anonymous)],
mockRejectedValue: [Function (anonymous)],
mockImplementationOnce: [Function (anonymous)],
mockImplementation: [Function (anonymous)],
mockReturnThis: [Function (anonymous)],
mockName: [Function (anonymous)],
getMockName: [Function (anonymous)]
}
But when I log Animated.createAnimatedComponent(FlatList)
it returns undefined
.
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 the Animated.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 returning undefined
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
- Clone the provided repo
- Run
npm i
to install the dependencies - Run
npx 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
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.