Reputation: 2000
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
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