Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jest: How can I mock out Animated loops?

I'm trying to run a snapshot test for an animated component which has the following animated code (called on componentDidMount):

animate() {
  Animated.loop(
    Animated.sequence([
      Animated.timing(this.state.pulseAnimation, {
        toValue: 1,
        duration: 1000,
        easing: Easing.in(Easing.ease)
      })
    ]),
    {
      iterations: this.props.totalNumPulses
    }
  ).start();
}

I've tried to mock Animated with the following:

  jest.mock('Animated', () => {
    return {
      loop: jest.fn(() => {
        return {
          start: jest.fn(),
          reset: jest.fn()
        };
      }),
      timing: jest.fn(() => {
        return {
          start: jest.fn(),
        };
      }),
      Value: jest.fn(() => {
        return {
          interpolate: jest.fn(),
        };
      }),
    };
  });

However, running the test results in this error:

TypeError: animation.reset is not a function

  54 |         iterations: this.props.totalNumPulses
  55 |       }
> 56 |     ).start();
  57 |   }
  58 | 

I've put the reset mocking in various places and checked the source code on the 'loop' method in React Native, but haven't had any luck successfully mocking it out. Has anyone successfully done this before?

like image 426
johnny kehr Avatar asked Jun 18 '18 20:06

johnny kehr


2 Answers

The issue in your example is that you are completely replacing Animated with an object, rather than only replacing the methods you need to test.

In the example below, I mock out parallel().start(callback) so that it immediately invokes the callback.

// Tests/__mocks__/react-native.js

export const Animated = {
  ...RN.Animated,
  parallel: () => ({
    // immediately invoke callback
    start: (cb: () => void) => cb()
  })
};

This allowed me to skip the animation and better test my start callback. You can use a similar approach for any property or subproperty of Animated!

like image 56
Brendan McGill Avatar answered Nov 01 '22 06:11

Brendan McGill


If you are using jest, you can create a mock for react-native inside your __mocks__ folder and mock specific function/method from react native that you need and leave the rest of react-native untouched.

import * as RN from 'react-native';

RN.Animated.timing = () => ({ // I'm mocking the Animated.timing here
    start: () => jest.fn(),
});

module.exports = RN;
like image 5
Renan Borges Avatar answered Nov 01 '22 05:11

Renan Borges