2017-02-16 1 views
11

Я пытаюсь выяснить, как протестировать событие onPress с помощью Jest в приложении React-Native, чтобы я мог убедиться в правильности вызывается функция.Как имитировать событие на единичном тесте с Jest, Enzyme for 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: document is not defined

Я попытался с shallow вместо но TouchableOpacity не получает вынесенное, когда я смотрю на выходе функции ... и вы уже догадались , он тоже не работает. Не уверен, что делать.

Кто-нибудь нашел способ проверить события на React-Native?

Благодаря

+1

Я предполагаю, что вы используете фермент, поэтому 'p.simulate ('нажмите');' должна работать. –

+0

Фермент 'mount', похоже, не работает с React-Native, и я не хочу использовать« мелкий ». 'ReferenceError: документ не определен' – alexmngn

+0

Какое событие вы пытаетесь протестировать? Изменилось ли это состояние? Или что именно пытаются проверить? Более подробная информация об этом может помочь. –

ответ

9

Фермент не поддерживает Реагировать родной, потому что она оказывается по-другому и не использует DOM. Вот почему вы получаете ошибку ReferenceError: document is not defined. Вы можете увидеть this issue для получения дополнительной информации. Команда 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').

Это хак, и я не уверен, каковы последствия этого, но он сработал для наших случаев использования.

+0

Спасибо за ваш ответ! «Команда React в настоящее время работает над тем, чтобы подвергать метод .find() в обработчике реакции-теста для имитации действий над компонентами». Любой источник для этого? – irrigator

+0

@irrigator Вот связанный PR https://github.com/facebook/react/pull/7409 –

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"] 
    } 
    } 
} 
+0

Спасибо, с мелким является хорошим вариантом, работает и для меня. Но бегите с неглубокими средствами, чтобы отменить жизненный цикл реагировать на родной. Идея состоит в том, чтобы заставить его работать, используя 'mount' вместо' мелкий' – jose920405

0

Вы должны использовать вместо shallow, то называется .dive()

const mockFunc = jest.fn(); 
const component = shallow(<MyComponent onPress={mockFunc} />);  
component.dive().simulate('press'); 
expect(mockFunc).toHaveBeenCalled();