I have a import { WebView } from 'react-native-webview';
from the react-native-community. Which is implemented in my react-native app like this:
<WebView
key={ this.state.uri }
source={{ uri: this.state.signedIn && this.state.shareUrl || this.state.uri }}
style={{ width: '100%', height: '100%' }}
onMessage={this.onMessage}
onNavigationStateChange={this.setWebViewUrlChanged}
onLoadEnd={syntheticEvent => {
this.setState({ loading: false });
}}
onLoadStart={syntheticEvent => {
this.setState({ loading: true });
}}
/>
The onNavigationStateChange prop is called when I, from the running application withing the webview call window.location.realod(url)
My handler function looks like this:
setWebViewUrlChanged = webviewState => {
if (webviewState.url !== this.state.initialUrl) {
this.setState({ uri: webviewState.url });
}
};
And is tested on phone and emulator, it works perfectly. I have even console logged state before/after and confirmed that state is updated and the function is called.
However, I am trying to test this with jest unit test.
it('should set webview uri', () => {
console.log(snap.children[0].children[0].children[0].children[0].props);
snap.children[0].children[0].children[0].children[0].props.onNavigationStateChange({ url: 'some-new-url' });
expect(snap.state().uri).toEqual('some-new-url');
});
When running the test I get error:
TypeError: snap.children[0].children[0].children[0].children[0].props.onNavigationStateChange is not a function
and from the console.log line above I get the webviews props, where this function is missing:
{ style:
[ { flex: 1 },
{ backgroundColor: '#ffffff' },
{ width: '100%', height: '100%' } ],
source:
{ uri: 'https://test-domain.eu.ngrok.io/static/dashboard/index.html' },
injectedJavaScript: undefined,
bounces: undefined,
scrollEnabled: undefined,
pagingEnabled: undefined,
cacheEnabled: true,
decelerationRate: undefined,
contentInset: undefined,
automaticallyAdjustContentInsets: undefined,
hideKeyboardAccessoryView: undefined,
allowsBackForwardNavigationGestures: undefined,
incognito: undefined,
userAgent: undefined,
onLoadingStart: [Function],
onLoadingFinish: [Function],
onLoadingError: [Function],
onLoadingProgress: [Function],
onMessage: [Function],
messagingEnabled: true,
onShouldStartLoadWithRequest: [Function],
scalesPageToFit: undefined,
allowsInlineMediaPlayback: undefined,
mediaPlaybackRequiresUserAction: undefined,
dataDetectorTypes: undefined,
useSharedProcessPool: true,
allowsLinkPreview: undefined,
showsHorizontalScrollIndicator: undefined,
showsVerticalScrollIndicator: undefined,
directionalLockEnabled: undefined }
So in the test rendered webview only the onMessage function is as in my object, but all my onLoadStart/End and the onNavigationStateChange
are not rendered.
But these functions that are missing works perfectly fine when project is compiled and running on device. How can I fix this, so that I can include unit tests for these functions?
The snap shot used in the test case is generated like so:
import renderer from 'react-test-renderer';
beforeEach(async () => {
snapshot = renderer.create(<App />);
snap = snapshot.toJSON();
});
I solved it by switching test renderer. I installed enzyme
, enzyme-to-json
, enzyme-adapter-react-16
Test modified:
describe('with setting', () => {
let snapshot;
beforeEach(async () => {
// some mocking of asyncStorage
});
it('should match snapshot', async () => {
snapshot = shallow(<App />)
await new Promise((resolve) => setTimeout(resolve, 100)); // to allow async componentDidMount to finish.
expect(snapshot).toMatchSnapshot()
});
it('should set webview uri', () => {
snapshot.find('WebView').props().onNavigationStateChange({ url: 'some-new-url' });
expect(snapshot.state().uri).toEqual('some-new-url');
});
});
The shallow
function comes from configuring enzyme for jest in setup.js
import Enzyme, { shallow, render, mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
// React 16 Enzyme adapter
Enzyme.configure({ adapter: new Adapter() });
// Make Enzyme functions available in all test files without importing
global.shallow = shallow;
global.render = render;
global.mount = mount;
The setup.js is pointet to in the jest configuration (in my case in package.json)
"jest": {
"preset": "react-native",
"snapshotSerializers": [
"enzyme-to-json/serializer"
],
"setupFiles": [
"<rootDir>/react-native/jest/setup.js"
]
}
Hope this will help others who have issues with misalignment of compiled rendered components and mocked (test) rendered component.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.