Jest: Jest для react-native распознаСт Π½Π΅ всС Ρ€Π΅ΠΊΠ²ΠΈΠ·ΠΈΡ‚Ρ‹ для<touchablehighlight/>

Π‘ΠΎΠ·Π΄Π°Π½Π½Ρ‹ΠΉ Π½Π° 16 сСнт. 2016  Β·  3ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ  Β·  Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: facebook/jest

Π£ мСня Π΅ΡΡ‚ΡŒ класс для настраиваСмой ΠΊΠ½ΠΎΠΏΠΊΠΈ:

import React, { Component } from 'react';
import { StyleSheet, View, TouchableHighlight, Text, Image } from 'react-native';

class NavBarBackButton extends Component {

  static propTypes = {
    onClick: React.PropTypes.func.isRequired,
    buttonText: React.PropTypes.string,
    customStyle: React.PropTypes.object
  };

  render() {

    return (
      <TouchableHighlight
        style={[styles.backButton, this.props.customStyle]}
        onPress={() => {this.props.onClick()}} >
        <View style={{flexDirection: 'row'}}>
          <Image
            style={styles.backImage}
            source={require('../img/back-128.png')}
          />
          <Text style={styles.backButtonText}>
            {this.props.buttonText}
          </Text>
        </View>
      </TouchableHighlight>
    );
  }
}

const styles = StyleSheet.create({
  backButton: {
    justifyContent: 'center'
  },
  backButtonText: {
    fontSize: 17,
    textAlignVertical: 'center',
    color: 'black',
  },
  backImage: {
    width: 40,
    height: 40
  },
});

export default NavBarBackButton;

ΠΈ снимок создаСтся с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ этого тСста:

import 'react-native';
import React from 'react';
import NavBarBackButton from '../navBarBackButton';

import renderer from 'react-test-renderer';

function doWork() {
  console.log('Back button was clicked!');
}

it('renders all UI elements', () => {

  const tree = renderer.create(
    <NavBarBackButton onClick = {doWork}/>
  ).toJSON();

  expect(tree).toMatchSnapshot();
});

Π½ΠΎ ΠΊΠΎΠ³Π΄Π° я добавляю Π΅Ρ‰Π΅ ΠΎΠ΄Π½Ρƒ ΠΎΠΏΠΎΡ€Ρƒ ΠΊ элСмСнту <TouchableHighlight/> , Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€:

underlayColor={'blue'}

ΠΈ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ запуститС тСст - я Π½Π΅ ΠΏΠΎΠ»ΡƒΡ‡Π°ΡŽ Ρ€Π°Π·Π½ΠΈΡ†Ρ‹, ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‰Π΅ΠΉ, Ρ‡Ρ‚ΠΎ снимок Π½Π΅ ΠΎΠΆΠΈΠ΄Π°Π» этой Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ ΠΎΠΏΠΎΡ€Ρ‹. ЀактичСски, СдинствСнный Ρ€Π΅ΠΊΠ²ΠΈΠ·ΠΈΡ‚ ΠΎΡ†Π΅Π½ΠΈΠ» ΡˆΠ²Ρ‹ ΠΊΠ°ΠΊ Β«ΡΡ‚ΠΈΠ»ΡŒΒ».
Π­Ρ‚Π° Ρ€Π°Π±ΠΎΡ‚Π° продолТаСтся?
ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, ΠΏΠΎ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΌΡƒ ΠΏΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΡŽ - ΠΏΠΎΡ‡Π΅ΠΌΡƒ Ρ‚ΠΈΠΏ TouchableHighlight отобраТаСтся Π² ΠΌΠΎΠΌΠ΅Π½Ρ‚Π°Π»ΡŒΠ½ΠΎΠΌ снимкС (ΠΈ ΠΎΡ‚Π»Π°Π΄Ρ‡ΠΈΠΊΠ΅) ΠΊΠ°ΠΊ Β«ViewΒ», Π° Π½Π΅ Β«TouchableHightlightΒ»?

Π’ ΠΌΠΎΠ΅ΠΌ package.jason Ρƒ мСня Π΅ΡΡ‚ΡŒ:

{
  "name": <my_project_name>,
  "version": "0.0.1",
  "private": true,
  "scripts": {
   "start": "node node_modules/react-native/local-cli/cli.js start",
    "test": "jest"
  },
  "jest": {
    "preset": "jest-react-native",
    "collectCoverage": true,
    "verbose": true,
    "preprocessorIgnorePatterns": [
      "node_modules/(?!react-native|<my_project_name>|react-native-button)"
    ]
  },
  "dependencies": {
    "lodash": "^4.15.0",
    "react": "^15.3.1",
    "react-native": "^0.33.0",
  },
  "devDependencies": {
    "babel-jest": "^15.0.0",
    "babel-polyfill": "^6.13.0",
    "babel-preset-react-native": "^1.9.0",
    "jest": "^15.1.1",
    "jest-cli": "^15.1.1",
    "jest-react-native": "^15.0.0",
    "react-addons-test-utils": "^15.2.1",
    "react-shallow-testutils": "^2.0.0",
    "react-test-renderer": "^15.3.1"
  }
}

ΠΈ ΠΌΠΎΠΉ .babelrc Π² ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠΌ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π΅:

{
  "presets": ["react-native"]
}

Π‘Π°ΠΌΡ‹ΠΉ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹ΠΉ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ

@cpojer Бпасибо Π·Π° быстрый ΠΎΡ‚Π²Π΅Ρ‚! Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΠΎΠΉ снимок выглядит Π½Π°ΠΌΠ½ΠΎΠ³ΠΎ Ρ‡ΠΈΡ‰Π΅.
Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ вопрос - Π² настоящСС врСмя ΠΌΠΎΠΉ Π²Ρ‹Π²ΠΎΠ΄ ТалуСтся Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ я Π½Π΅ ΠΏΠΎΠΊΡ€Ρ‹Π²Π°ΡŽ строку, которая ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ onPress prop ΠΊΠ°ΠΊ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½ΡƒΡŽ Π²

static propTypes = {
    onClick: React.PropTypes.func.isRequired,
    ...
};

<TouchableHighlight
    onPress={() => {this.props.onClick()}} > //no coverage for this line of code in test
    ...
</TouchableHighlight>

Π•ΡΡ‚ΡŒ ΠΈΠ΄Π΅ΠΈ, ΠΊΠ°ΠΊ ΠΈΠΌΠΈΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π½Π°ΠΆΠ°Ρ‚ΠΈΠ΅ ΠΊΠ½ΠΎΠΏΠΊΠΈ? Или ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Ρ‡Ρ‚ΠΎ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ мою Ρ‚Π΅ΡΡ‚ΠΎΠ²ΡƒΡŽ ΠΎΠ±Π»ΠΎΠΆΠΊΡƒ onPress={() => {this.props.onClick()}} > ? Π― Π½Π΅ смог Π½Π°ΠΉΡ‚ΠΈ Π² Π²Π°ΡˆΠΈΡ… ΡƒΡ€ΠΎΠΊΠ°Ρ… Π½ΠΈΡ‡Π΅Π³ΠΎ ΠΏΠΎ этой Ρ‚Π΅ΠΌΠ΅.

Π—Π°Ρ€Π°Π½Π΅Π΅ спасибо!

ВсС 3 ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ

ΠœΡ‹ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎ Π½Π΅ издСваСмся Π½Π°Π΄ TouchableHighlight. Он отобраТаСтся ΠΊΠ°ΠΊ View, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ это Ρ‚ΠΎ, Π½Π° Ρ‡Ρ‚ΠΎ Π΅Π³ΠΎ отрисовываСт react-native.

ΠŸΠΎΡ…ΠΎΠΆΠ΅, Ρ‡Ρ‚ΠΎ TouchableHighlight устанавливаСт Ρ€Π΅ΠΊΠ²ΠΈΠ·ΠΈΡ‚Ρ‹ нСпосрСдствСнно Π½Π° свой собствСнный элСмСнт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ: https://github.com/facebook/react-native/blob/master/Libraries/Components/Touchable/TouchableHighlight.js#L200, ΠΈ Π²Π°ΠΌ понадобится ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΉ ΠΌΠ°ΠΊΠ΅Ρ‚ для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ваша ΠΎΠΏΠΎΡ€Π° ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π»Π°ΡΡŒ Π² Π²ΠΈΠ·ΡƒΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠΌ Π²Ρ‹Π²ΠΎΠ΄Π΅.

Одна Π²Π΅Ρ‰ΡŒ, которая ΠΌΠΎΠΆΠ΅Ρ‚ ΡΡ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ, - это ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ свой собствСнный ΠΌΠ°ΠΊΠ΅Ρ‚, ΠΊΠ°ΠΊ ΠΏΡ€Π΅Π΄Π»ΠΎΠΆΠ΅Π½ΠΎ Π²ΠΎ Π²Ρ‚ΠΎΡ€ΠΎΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Π½Π° Π²Π΅Π±-сайтС: http://facebook.github.io/jest/docs/tutorial-react-native.html#mock -native-modules- использованиС-ΡˆΡƒΡ‚ΠΊΠ°-ΠΈΠ·Π΄Π΅Π²Π°Ρ‚Π΅Π»ΡŒΡΡ‚Π²ΠΎ

jest.mock('TouchableHighlight', () => {
  const jestReactNative = require('jest-react-native');
  return jestReactNative.mockComponent('TouchableHighlight');
});

@cpojer Бпасибо Π·Π° быстрый ΠΎΡ‚Π²Π΅Ρ‚! Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΠΎΠΉ снимок выглядит Π½Π°ΠΌΠ½ΠΎΠ³ΠΎ Ρ‡ΠΈΡ‰Π΅.
Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ вопрос - Π² настоящСС врСмя ΠΌΠΎΠΉ Π²Ρ‹Π²ΠΎΠ΄ ТалуСтся Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ я Π½Π΅ ΠΏΠΎΠΊΡ€Ρ‹Π²Π°ΡŽ строку, которая ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ onPress prop ΠΊΠ°ΠΊ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½ΡƒΡŽ Π²

static propTypes = {
    onClick: React.PropTypes.func.isRequired,
    ...
};

<TouchableHighlight
    onPress={() => {this.props.onClick()}} > //no coverage for this line of code in test
    ...
</TouchableHighlight>

Π•ΡΡ‚ΡŒ ΠΈΠ΄Π΅ΠΈ, ΠΊΠ°ΠΊ ΠΈΠΌΠΈΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π½Π°ΠΆΠ°Ρ‚ΠΈΠ΅ ΠΊΠ½ΠΎΠΏΠΊΠΈ? Или ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Ρ‡Ρ‚ΠΎ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ мою Ρ‚Π΅ΡΡ‚ΠΎΠ²ΡƒΡŽ ΠΎΠ±Π»ΠΎΠΆΠΊΡƒ onPress={() => {this.props.onClick()}} > ? Π― Π½Π΅ смог Π½Π°ΠΉΡ‚ΠΈ Π² Π²Π°ΡˆΠΈΡ… ΡƒΡ€ΠΎΠΊΠ°Ρ… Π½ΠΈΡ‡Π΅Π³ΠΎ ΠΏΠΎ этой Ρ‚Π΅ΠΌΠ΅.

Π—Π°Ρ€Π°Π½Π΅Π΅ спасибо!

@rosiakr Π”Π°, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΡ€ΠΎΡ‚Π΅ΡΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ событиС наТатия ΠΊΠ½ΠΎΠΏΠΊΠΈ.
Π’ΠΎΡ‚ ΠΊΠΎΠ΄, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ я написал для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ наТатия ΠΊΠ½ΠΎΠΏΠΊΠΈ.

class YourComponent extends Component {
  handleButtonClick = () => {};

  render() {
    return <Button transparent onPress={() => this.handleButtonClick()}></Button>
  }
}

//jest
it("Test Component", () => {
  const component = renderer.create(
    <YourComponent/>
  );

  // manually trigger the  button click.
  component.getInstance().handleButtonClick();
};
Π‘Ρ‹Π»Π° Π»ΠΈ эта страница ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ?
0 / 5 - 0 Ρ€Π΅ΠΉΡ‚ΠΈΠ½Π³ΠΈ