React-native-reanimated: createAnimatedComponent is not a function when using mock

Created on 30 Jul 2019  路  7Comments  路  Source: software-mansion/react-native-reanimated

I have created a component which I want to test, and the component uses react-native-reanimated to handle its animations. Per the documentation in mock.js, I have added the following line to __mocks__/react-native-reanimated.js:

jest.mock('react-native-reanimated', () => require('react-native-reanimated/mock'));

Expected Behavior

Tests will pass without error.

Actual Behavior

When I run my tests, they fail with the following error:
TypeError: _reactNativeReanimated.default.createAnimatedComponent is not a function

Files

Component.js (imports and styles omitted for clarity):

const { Value, Clock, useCode, set, cond, eq, block, stopClock, multiply, interpolate } = Animated;
const Component = function(props: Props){
    const clock1 = new Clock(); // manages moving up
    const clock2 = new Clock(); // manages moving down
    const animState = new Animated.Value(0); // 0 = down, 1 = elevated
    const move = new Animated.Value(0);

    useCode(
        block([
            cond(eq(animState, 0), [stopClock(clock2), set(move, runTiming(clock1, move, {
                duration: 350,
                toValue: 0,
                easing: Easing.linear
            }))]),
            cond(eq(animState, 1), [stopClock(clock1), set(move, runTiming(clock2, move, {
                duration: 350,
                toValue: 1,
                easing: Easing.linear
            }))])
        ])
    )

    const translation = interpolate(move, {
        inputRange: [0, 1],
        outputRange: [0, -20]
    });

    return (
        <View style={props.style}>
            <TouchableWithoutFeedback onPressIn={() => animState.setValue(1)} onPressOut={() => animState.setValue(0)} onPress={props.onPress}>
                <Animated.View style={
                    [styles.card, 
                    {transform: [{translateX: translation}, {translateY: translation}]}
                ]}>
                    <ImageBackground source={props.image} style={styles.imageBackground} imageStyle={styles.cardImage}>
                            <Text style={styles.title}>Hi</Text>
                    </ImageBackground>
                </Animated.View>
            </TouchableWithoutFeedback>
        </View>
    )
}

export default Component;

Component.test.js:

import React from 'react';
import { fireEvent, render, wait } from '@testing-library/react-native';
import Component from '../../components/Component';

test('should call the onClick', () => {
    const clickFunction = jest.fn();
    const props = {
        onClick: clickFunction,
        image: require("/path/to/image.png")
    }
    const {getByText} = render(<Component {...props}/>)
    fireEvent.press(Component);
    expect(clickFunction.mock.calls.length).toBe(1);
})

Additionally, I have confirmed that jest is indeed using the provided mock, as I receive a different error when the mock is not used. Any thoughts? I'm guessing createAnimatedComponent needs to be added to the mock somehow.

Most helpful comment

馃憤

is it written in doc/readme that we can set up jset like this?

jest.mock('react-native-reanimated', () => require('react-native-reanimated/mock'));

Found about it by searching the issues, it'd be time-saving if it's somewhere visible (_can we update the PR to add it somewhere?_)

All 7 comments

Alright, I was able to solve this issue by adding the following line to mock.js on line 100 (so in the default key):

createAnimatedComponent: NOOP

Now, I am faced with a new error:
TypeError: Clock is not a constructor

Based on this stackoverflow, I think it has something to do with the fact that NOOP is an arrow function. I tried using a class instead of NOOP for the mock file, but that didn't work either. Any thoughts?

We ended up replacing NOOP with a plain old js function, it works so far.

function NOOP() {}

Also createAnimatedComponent as an identity function is a better choice to avoid React.createElement errors.

createAnimatedComponent: Component => Component,

馃憤

is it written in doc/readme that we can set up jset like this?

jest.mock('react-native-reanimated', () => require('react-native-reanimated/mock'));

Found about it by searching the issues, it'd be time-saving if it's somewhere visible (_can we update the PR to add it somewhere?_)

@mustafawm Good point, I'll open a PR for that to update the doc
@kmagiera since https://github.com/kmagiera/react-native-reanimated/pull/389 has been merged I think you can close this issue

this issue can also be fixed by exposing the module to babel:

   "transformIgnorePatterns": [
      "node_modules/(?!(react-native|react-native-screens|react-native-reanimated)/)"
    ]

This issue seems resolved, so I'm closing it.

In my __mocks__/react-native-reanimated.js file I have

jest.mock('react-native-reanimated', () => require('react-native-reanimated/mock'));

but when I execute npm run test, I get TypeError: _reactNativeReanimated.default.Value is not a constructor error.

"react": "16.11.0",
"react-native": "0.62.0",
"react-native-reanimated": "^1.8.0",
"jest": "^24.9.0",
Was this page helpful?
0 / 5 - 0 ratings

Related issues

mrousavy picture mrousavy  路  3Comments

dinhmai74 picture dinhmai74  路  3Comments

bdrobinson picture bdrobinson  路  3Comments

zxccvvv picture zxccvvv  路  3Comments

alexfov picture alexfov  路  3Comments