我有一个来自react-native-community的import { WebView } from 'react-native-webview';
。这是在我的 react native 应用程序中实现的,如下所示:
<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 });
}}
/>
当我从正在运行的应用程序中使用 webview 调用 window.location.realod(url)
我的处理函数如下所示:
setWebViewUrlChanged = webviewState => {
if (webviewState.url !== this.state.initialUrl) {
this.setState({ uri: webviewState.url });
}
};
并在手机和模拟器上进行了测试,完美运行。我什至在控制台之前/之后记录了状态,并确认状态已更新并且函数被调用。
但是,我正在尝试使用 Jest 单元测试来测试它。
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');
});
运行测试时出现错误:
TypeError: snap.children[0].children[0].children[0].children[0].props.onNavigationStateChange is not a function
从上面的 console.log 行中我得到了 webviews 属性,其中缺少此功能:
{ 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 }
因此,在测试渲染的 webview 中,只有 onMessage 函数与我的对象中相同,但我所有的 onLoadStart/End 和 onNavigationStateChange
都没有渲染。
但是当项目编译并在设备上运行时,这些缺少的功能可以完美地工作。我该如何解决这个问题,以便我可以包含这些函数的单元测试?
测试用例中使用的快照是这样生成的:
import renderer from 'react-test-renderer';
beforeEach(async () => {
snapshot = renderer.create(<App />);
snap = snapshot.toJSON();
});
最佳答案
我通过切换测试渲染器解决了这个问题。我安装了enzyme
、enzyme-to-json
、enzyme-adapter-react-16
测试修改:
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');
});
});
shallow 函数来自于在 setup.js 中为 jest 配置 enzyme
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;
setup.js 指向 jest 配置(在我的例子中是 package.json)
"jest": {
"preset": "react-native",
"snapshotSerializers": [
"enzyme-to-json/serializer"
],
"setupFiles": [
"<rootDir>/react-native/jest/setup.js"
]
}
希望这能帮助其他遇到编译渲染组件和模拟(测试)渲染组件未对齐问题的人。
关于javascript - React Native WebView onNavigationStateChange 不是一个函数(运行 jest 测试时),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56021335/