2017-02-16 2 views
11

React-Native 앱에서 Jest로 "onPress"이벤트를 테스트하는 방법을 알아 내려고합니다. 함수가 호출됩니다.Jest, React-Native 용 효소를 사용하여 단위 테스트에서 이벤트를 시뮬레이트하는 방법

필자는 설명서와 Google을 검토했지만 React-Native에서 해결책을 찾지 못했습니다.

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

그러나이 작동하지 않습니다 : 이것은 내가 그이 반작용 네이티브 enzyme와 작동하도록되어 찾을 것입니다

. mount처럼 보인다 작동하지 않습니다와 나는이 출력 얻을 :

ReferenceError: document is not defined

내가 대신 shallow과 노력하지만 함수의 출력에서 ​​볼 때 TouchableOpacity 렌더링지고 있지 않습니다 ... 그리고 당신은 그것을 짐작 , 그것도 작동하지 않습니다. 무엇을해야할지 모르겠습니다.

누구나 React-Native에서 이벤트를 테스트 할 수있는 방법을 찾았습니까?

감사

+1

.dive()을했다. –

+0

효소'mount'가 React-Native에서 작동하지 않는 것처럼 보이고'shallow'를 사용하고 싶지 않습니다. 'ReferenceError : 문서가 정의되지 않았습니다. ' – alexmngn

+0

어떤 종류의 이벤트를 테스트하려고합니까? 그것은'국가'를 바꾸는가? 또는 정확히 무엇을 테스트하려고합니까? 그 주변의 세부 정보가 도움이 될 수 있습니다. –

답변

9

가 다르게 렌더링 그리고 DOM을 사용하지 않기 때문에 효소가, 반작용 네이티브를 지원하지 않습니다. 그래서 ReferenceError: document is not defined 오류가 발생합니다. 자세한 내용은 this issue을 참조하십시오. React 팀은 현재 react-test-renderer.find() 메서드를 표시하여 구성 요소에 대한 동작을 시뮬레이션합니다. 그런 다음 DOM 환경이 필요없이 React/React-native 모두에서 작동해야합니다.

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의 질문에서 설명한 것과 같은 테스트를 실행할 수 있습니다./

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 

예 구성 요소 jestSetup.js

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

시험 :

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

감사합니다. 얕은 옵션은 나에게도 효과적입니다. 그러나 반응이 빠른 네이티브 라이프 사이클을 따로 설정하려면 얕은 수단으로 실행하십시오. 아이디어는'shallow' 대신에'mount'를 사용하여 동작하도록 만드는 것입니다. – jose920405

0

대신 shallow를 사용한다, 그럼 내가 ('눌러'),이 효소를 사용하므로`p.simulate 가정

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