Search code examples
reactjsjestjsenzymevideo-reactjs

How do I mock callbacks on a ref for testing in react?


I am using video-react in a react application. I have to test a component that calls ref methods from a video-react component. I hope to use enzyme so I can mount the component and check that I have called the ref method in ComponentDidMount.

Basically, how do I test that refs.player.seek gets called like it does below?

componentDidMount() {
    this.refs.player.seek(this.props.currentTime);
    this.refs.player.subscribeToStateChange(this.handlePlayerStateChange);
}

Solution

  • Since video-react requires refs to call play, pause and seek to my knowledge, I ended up using this pattern so I could mock my own ref callbacks hitting render methods.

    https://medium.com/@planttheidea/never-render-in-react-testing-again-fc4bcfc2f71d

    example component code:

    export const createComponentWillReceiveProps = instance => ({seekTime, isPlaying, onSeekComplete}) => {
      const {paused} = instance.playerRef.getState().player;
    
      if (seekTime) {
        instance.playerRef.seek(seekTime);
        onSeekComplete();
      }
      if (isPlaying && paused) {
        instance.playerRef.play();
      }
      if (!isPlaying && !paused) {
        instance.playerRef.pause();
      }
    };
    

    ...

    componentWillReceiveProps = createComponentWillReceiveProps(this)
    

    ...

    <VideoReactPlayer ref={el => this.playerRef = el} preload='auto' src={source}>
    

    ...

    and the tests looked like this:

      it('calls playerRef.play when isPlaying prop is true & paused is true', () => {
        const instance = {playerRef: {play: jest.fn(), getState: () => ({player: {paused: true}})}};
        const componentWillReceiveProps = createComponentWillReceiveProps(instance);
        componentWillReceiveProps({isPlaying: true});
        expect(instance.playerRef.play).toBeCalled();
      });