Подтвердить что ты не робот

Как имитировать событие на 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?

Спасибо

4b9b3361

Ответ 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();