react-native-reanimated: Testing error: useSharedValue is not a function while testing

Description

useSharedValue throws an error that it’s not a function when using jest and react-native-testing-library. I’ve mocked react-native-reanimated by using the mock provided as part of the package. I also notice VS Code highlights that reanimated has no exported member useSharedValue, useAnimatedStyle and withTiming, however the component still runs properly without any errors.

Does anyone know what needs to be done to mock it properly?

Screenshots

Screen Shot 2020-07-07 at 2 48 22 PM image

Steps To Reproduce

  1. Create the simple switch component
  2. Create the mock file
  3. Create the test
  4. Run the test

Expected behavior

I expected the render test to pass since I’m successfully mocking react-native-reanimated

Actual behavior

The render test fails due to useSharedValue not being a function. "TypeError: (0 , _reactNativeReanimated.useSharedValue) is not a function"

Snack or minimal code example

The Test to see if the component renders

`import React from “react”; import { render } from “react-native-testing-library”; import { Switch } from “…/src/native/Switch”;

describe(“Switch Package”, () => { it(“renders”, () => { render(<Switch />); }); });`

Mock file which is placed in mocks named react-native-reanimated.js

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

The Component using Reanimated - Switch.tsx `import { Button } from ‘react-native’; import { useSharedValue, useAnimatedStyle, withTiming, Easing, } from ‘react-native-reanimated’;

function Switch() { const opacity = useSharedValue(0);

const style = useAnimatedStyle(() => { return { opacity: withTiming(opacity.value, { duration: 200, easing: sing.out(Easing.cubic), }), }; });

return ( <View> <Animated.View style={[{width: 100, height: 100, backgroundColor: ‘green’}, style]} /> <Button onPress={() => (opacity.value = 1)} title=“Hey” /> </View> ); }`

Package versions

  • React: 16.11.0
  • React Native: .062.2
  • React Native Reanimated: 2.0.0-alpha.3

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 1
  • Comments: 26 (13 by maintainers)

Most upvoted comments

if you have just installed Reanimated, make sure to run packager again with --reset-cache.

Also, for your animation you can do something like that:

const dummyAnimation = (props: any) => {
  const [isKeyboardOpen, setIsKeyboardOpen] = useState(false);

  useEffect(() => {
    const keyboardDidShowListener = Keyboard.addListener(
      "keyboardDidShow",
      () => {
        setIsKeyboardOpen(true);
      }
    );
    const keyboardDidHideListener = Keyboard.addListener(
      "keyboardDidHide",
      () => {
        setIsKeyboardOpen(false);
      }
    );
    return () => {
      keyboardDidHideListener.remove();
      keyboardDidShowListener.remove();
    };
  }, []);

  const borderRadiusStyle = useAnimatedStyle(() => {
    return {
      width: withTiming(isKeyboardOpen ? 22 : 0, {
        duration: 400,
      }),
    };
  }, [isKeyboardOpen]);

  return (
    <Animated.View
      style={borderRadiusStyle}
    >
      <Text>{"this is animating"}</Text>
    </Animated.View>
  );
};

Could you try to use import from “src”

import {
  useAnimatedStyle,
  useSharedValue,
  withTiming,
} from "react-native-reanimated/src/Animated";

But also it’s weird your project doesn’t have a babel config file. At least the default one should be

I tried this solution as well but this also did not work.

We hotfixed it in our jest.setup file, by doing this:

const mock = jest.requireMock("react-native-reanimated");
jest.mock("react-native-reanimated", () => {
  return {
    ...mock,
    useSharedValue: jest.fn,
    useAnimatedStyle: jest.fn,
  };
});

however, I am not sure if the component which is being tested still behaves correctly with that.

requireMock("react-native-reanimated/mock");

worked for me.

if you have just installed Reanimated, make sure to run packager again with --reset-cache.

Also, for your animation you can do something like that:

const dummyAnimation = (props: any) => {
  const [isKeyboardOpen, setIsKeyboardOpen] = useState(false);

  useEffect(() => {
    const keyboardDidShowListener = Keyboard.addListener(
      "keyboardDidShow",
      () => {
        setIsKeyboardOpen(true);
      }
    );
    const keyboardDidHideListener = Keyboard.addListener(
      "keyboardDidHide",
      () => {
        setIsKeyboardOpen(false);
      }
    );
    return () => {
      keyboardDidHideListener.remove();
      keyboardDidShowListener.remove();
    };
  }, []);

  const borderRadiusStyle = useAnimatedStyle(() => {
    return {
      width: withTiming(isKeyboardOpen ? 22 : 0, {
        duration: 400,
      }),
    };
  }, [isKeyboardOpen]);

  return (
    <Animated.View
      style={borderRadiusStyle}
    >
      <Text>{"this is animating"}</Text>
    </Animated.View>
  );
};

Hi @terrysahaidak , I referred the document’s limitation section and found out I can work with flipper so I did the setup of that and now able to see log, but in above code as you corrected me earlier, I am getting 2 odd things,

  1. useAnimatedStyle hook where I am passing one parameter which is “isKeyboardOpen” I am getting an error in code, expected 1 argument but got 2 and
  2. I tried consoling the value of constant “borderRadiusStyle” that is not changing on change of keyboard open and close from ternary condition.

By any chance will you be able to help please?

Could you try to use import from “src”

import {
  useAnimatedStyle,
  useSharedValue,
  withTiming,
} from "react-native-reanimated/src/Animated";

But also it’s weird your project doesn’t have a babel config file. At least the default one should be