de3
de3

Reputation: 2000

How to mock third-party library custom events with jest and react testing library

I am using a third party library 'react-youtube' which has some methods

import Youtube from 'react-youtube';

const PlaySection: FunctionComponent<Props> = ({ ytPlayer, setYtPlayer }) => {
  const [playerState, setPlayerState] = useState<PlayerState>('stopped');

  const onClickFn = (state: PlayerState) => {
     ....
  };

  return (
    <div>
      <YoutubeWrapper>
        <Youtube
          videoId={'aasdfasdf'}
          onReady={(e: { target: YT.Player }) => setYtPlayer(e.target)}
          onStateChange={(e: { data: number }) => setPlayerState(getPlayerState(e.data))}
        />
      </YoutubeWrapper>
      {!!ytPlayer && (
        <Player
          playerState={playerState}
          onPlay={() => onClickFn('playing')}
          onPause={() => onClickFn('paused')}
          onStop={() => onClickFn('stopped')}
        />
      )}
    </div>
  );
};

How can I mock the 'Youtube' component and make 'onReady' and 'onStateChange' events fire with 'jest' and/or 'React test library'?

I can imagine creating a mocked Youtube component which would have a button that would trigger 'onReady' when clicking on it. Then I could just use 'fireEvent.click' but I feel there should be a better way to do that.

Upvotes: 2

Views: 2409

Answers (1)

thedude
thedude

Reputation: 9812

Not claiming this is best practice or anything, but I have been using this approach successfully.

Use jest.spyOn to supply an alternate implementation for the component you want to mock:

import * as YoutubeModule from 'react-youtube'


describe('My Cool Video Player', () => {
    let onReady, onStateChange
    beforeEach(() => {
        jest.spyOn(YoutubeModule, 'default')
          .mockImplementation(({ onReady, onStateChange  }) => {
             mockOnReady = onReady
             mockOnStateChange = onStateChange
             return <div>I am a mocked YouTube player</div>
         })
    })

    it('should do something', () => {
       act(() => {
           mockOnReady()
       })
       expect(readiness).toBeTruthy()
     })
})

Upvotes: 0

Related Questions