How can I mock react-native-webview reload function?

Viewed 632

I'm trying to create a unit test for a component in which I have a WebView.

The problem is that inside this component I call the reload() function of the WebView.

And when I run the test I get this error:

 Invariant Violation: nodeHandle expected to be non-null

      107 |     useCallback(() => {
      108 |       if (navigation.getState().index === 0) {
    > 109 |         webviewRef.current.reload();
          |                            ^
      110 |       }
      111 |     }, [webviewRef, navigation])
      112 |   );

I tried to mockup the reload() function following an example that I've found on Jest site in this way:

jest.mock('react-native-webview', () => {
  const RealComponent = jest.requireActual('react-native-webview');
  RealComponent.reload = jest.fn();
  return RealComponent;
});

But I'm getting the exact same error message. It seems that jest isn't picking my mockup.

How can I mockup the reload() function of WebView?

1 Answers

You could try creating a Node module mock of react-native-webview.

Assuming a component TestComponent.tsx:

import React, { useEffect, useRef } from 'react'
import { WebView } from 'react-native-webview'

export const TestComponent = () => {
  const webViewRef = useRef<WebView>(null)

  useEffect(() => {
    webViewRef.current?.reload()
  }, [])

  return <WebView ref={webViewRef} source={{ uri: `https://stackoverflow.com` }} />
}

In __mocks__/react-native-webview.tsx we could have this:

import React, { forwardRef, useImperativeHandle } from 'react'
import { View } from 'react-native'

export const refFunctions = {
  reload: jest.fn(),
}

export const WebView = forwardRef((_props, ref) => {
  useImperativeHandle(ref, () => refFunctions)
  return <View />
})

The test for this component could look like this:

import React from 'react'
import { render } from '@testing-library/react-native'
import { refFunctions } from '__mocks__/react-native-webview'
import { TestComponent } from './TestComponent'

describe('TestComponent', () => {
  afterEach(jest.clearAllMocks)
  it('reloads webview when component mounts', () => {
    render(<TestComponent />)
    expect(refFunctions.reload).toHaveBeenCalledTimes(1)
  })
})
Related