React-NativeアプリでJestを使用して「onPress」イベントをテストする方法を理解しようとしています。これにより、適切な関数が呼び出されることを確認できます。
ドキュメントとGoogleを確認しましたが、React-Nativeで解決策が見つかりませんでした。
これは、enzyme
を使用してReact-Nativeで動作するはずであることがわかったものです。
const mockFunc = jest.fn();
const component = mount(<MyComponent onPress={mockFunc} />);
component.simulate('press');
expect(mockFunc).toHaveBeenCalled();
しかし、これは機能しません。 mount
が機能しないようで、次の出力が表示されます。
ReferenceError:ドキュメントが定義されていません
代わりにshallow
を試しましたが、関数の出力を見るとTouchableOpacity
がレンダリングされていません...そして、ご想像のとおり、それも機能しません。何をすべきかわからない。
誰かがReact-Nativeでイベントをテストする方法を見つけましたか?
ありがとう
Enzymeは、レンダリングが異なり、DOMを使用しないため、React-Nativeをサポートしていません。そのため、_ReferenceError: document is not defined
_エラーが発生します。詳細は this issue を参照してください。 Reactチームは現在、コンポーネントのアクションをシミュレートするために_react-test-renderer
_で.find()
メソッドを公開するように取り組んでいます。 DOM環境が必要です。
TouchableOpacity
を拡張してonClick
を呼び出してonPress
を呼び出すカスタムコンポーネントをレンダリングすることで、あなたができるハックがあります(私たちの会社ではそれを行っています)。このようなもの:
_const mockPressable = (name) => {
const RealComponent = require.requireActual(name);
class Component extends RealComponent {
render() {
return React.createElement(
RealComponent.displayName || RealComponent.name,
{ ...this.props, onClick: this.props.onPress },
this.props.children
);
}
}
return Component;
};
jest.mock('TouchableOpacity', () => mockPressable('TouchableOpacity'));
_
そして、テストコードではcomponent.simulate('click')
を呼び出します。
それはハックであり、これを行うことの結果がどうなるかはわかりませんが、私たちのユースケースではうまくいきました。
React Native。
package.json
"scripts": {
...
"test": "node_modules/jest/bin/jest.js",
}
"devDependencies": {
...
"enzyme": "^3.1.0",
"enzyme-adapter-react-16": "^1.0.1",
"enzyme-to-json": "^3.1.2",
"jest": "^21.2.1",
"jest-enzyme": "^4.0.0",
"jest-expo": "~21.0.0",
}
"jest": {
"preset": "jest-expo",
"setupFiles": [
"./test/jestSetup.js"
],
"snapshotSerializers": [
"./node_modules/enzyme-to-json/serializer"
]
}
test/jestSetup.js
import { configure, shallow, render, mount } from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
configure( { adapter: new Adapter() } )
// enzyme
global.shallow = shallow
global.render = render
global.mount = mount
コンポーネントの例:
import React from 'react'
import { Button } from 'react-native'
const CancelButton = ( props ) =>
<Button
{ ...props }
onPress={ () => { props.navigation.goBack() } }
title="Cancel"
/>
export { CancelButton }
テストの例
import React from 'react'
import { CancelButton } from '../CancelButton'
test( 'onPress', () => {
const goBackFunc = jest.fn()
const navigation = {
goBack: goBackFunc,
}
const component = shallow(
<CancelButton
navigation={ navigation }
/>
)
component.simulate( 'press' )
expect( goBackFunc ).toHaveBeenCalled()
} )
.babelrc
{
"presets": ["babel-preset-expo"],
"env": {
"development": {
"plugins": ["transform-react-jsx-source"]
}
}
}
代わりにshallow
を使用し、次に.dive()
を呼び出す必要があります
const mockFunc = jest.fn();
const component = shallow(<MyComponent onPress={mockFunc} />);
component.dive().simulate('press');
expect(mockFunc).toHaveBeenCalled();