Как имитировать событие на unit test с помощью Jest, Enzyme for React-Native
Я пытаюсь выяснить, как протестировать событие onPress с помощью Jest в приложении React-Native, чтобы я мог убедиться, что вызывается правильная функция.
Я просмотрел документацию и Google, но не смог найти решение для этого в React-Native.
Это то, что я нашел, которое должно работать для React-Native с enzyme
:
const mockFunc = jest.fn();
const component = mount(<MyComponent onPress={mockFunc} />);
component.simulate('press');
expect(mockFunc).toHaveBeenCalled();
Но это не работает. Кажется, что mount
не работает, и я получаю этот вывод:
ReferenceError: документ не определен
Я попробовал вместо shallow
, но TouchableOpacity
не получает визуализацию, когда я смотрю на вывод функции... и вы догадались, что это тоже не работает. Не уверен, что делать.
Кто-нибудь нашел способ проверить события на React-Native?
Спасибо
Ответы
Ответ 1
Фермент не поддерживает React-Native, потому что он визуализируется по-разному и не использует DOM. Вот почему вы получаете ошибку ReferenceError: document is not defined
. Вы можете увидеть эту проблему для получения дополнительной информации. Команда React в настоящее время работает над тем, чтобы выставить метод .find()
в react-test-renderer
для имитации действий над компонентами. Затем он должен работать как для React/React-native, не нуждаясь в среде 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')
.
Это взломать, и я не уверен, каковы последствия этого, но он работал для наших случаев использования.
Ответ 2
Я могу запускать тесты, как то, что вы описали в своем вопросе в 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"
]
}
Тест/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"]
}
}
}
Ответ 3
Вместо этого следует использовать shallow
, а затем вызвать .dive()
const mockFunc = jest.fn();
const component = shallow(<MyComponent onPress={mockFunc} />);
component.dive().simulate('press');
expect(mockFunc).toHaveBeenCalled();