Тестовая кнопка onClick в функции react-native

Я пытаюсь написать свое первое приложение, используя собственный фреймворк React. У меня проблема с тестом функции onClick для кнопки.

Мой код App.js:

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { Button } from 'react-native';

export default class App extends React.Component {
  refreshData() {
    console.info("download data from server placeholder");
  }
  render() {
    return (
      <View style = {styles.container}>
        <Text>Shake your phone to open the developer menu.</Text>
        <Button
          id = "refreshButton"
          onPress = {this.refreshData}
          title = "Refresh"
          color = "#000000"
          accesibilityLabel = "Refresh AQI data"
          testID = "refreshButton"
        />
      </View>
    );
  }
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

Мой код App.test.js:

import React from 'react';
import App from './App';

import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

Enzyme.configure({ adapter: new Adapter() });

import renderer from 'react-test-renderer';
import { shallow, mount, render } from 'enzyme';

it('should render without throwing an error', function() {
  const wrapper = shallow(<App />);
  const refreshData = jest.fn();
  expect(wrapper.find('#refreshButton')).toHaveLength(1); // pass
  wrapper.find('#refreshButton').first().simulate('click');
  expect(refreshData).toHaveBeenCalledTimes(1); // fail
});

Когда я запускаю npm test, мой тест терпит неудачу, потому что refreshData вызывается ноль раз. Похоже, что функция моделирования не работает, почему? Я пробовал симулировать вызов без функции first (), но это не сработало. Я не знаком с javascript, может я сделал очевидную ошибку? Я нашел этот код в документации и некоторых руководствах, которые я нашел в Интернете. Я пишу простое приложение для iOS только для себя и для тренировок, и я большой поклонник TDD. Это причина того, что модульные тесты важны для меня.

Имеет ли значение изменение на onPress = {() => this.refreshData ()}?

Simon Johansson 10.03.2018 13:28

К сожалению нет. У меня нет проблем с методом onPress, потому что он работает в симуляторе. У меня проблема только с тестами.

esio 10.03.2018 17:29
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
4
2
2 311
3

Ответы 3

Измените часть onPress = {this.refreshData} следующим образом:

onClick = {this.refreshData}

Это не работает, потому что для реагирования требуется метод onPress.

esio 10.03.2018 17:27

Я не уверен, что фермент поддерживает селекторы ID и #. Попробуйте добавить опору testID и назвать ее так:

wrapper.dive().find("[testID='yourTestID']").simulate("press");

или же

wrapper.dive().find("[testID='yourTestID']").onPress();

Я использую оба, и они отлично работают.

Обновлено: теперь ваша проблема в этом

const refreshData = jest.fn ();

Измените на:

const refreshData = jest.spyOn (wrapper.instance (), «refreshData»);

Edit2:

Обновите код кнопки до этого:

<Button
          id = "refreshButton"
          onPress = {this.refreshData}
          title = "Refresh"
          color = "#000000"
          accesibilityLabel = "Refresh AQI data"
          testID = "refreshButton"
        />

и тестовый код для этого:

it('should render without throwing an error', function() {
  const wrapper = shallow(<App />);
  let refreshData = jest.spyOn(wrapper.instance(), "refreshData");
  expect(wrapper.find('#refreshButton')).toHaveLength(1);
  wrapper.find("[testID='refreshButton']").onPress();
  expect(refreshData).toHaveBeenCalledTimes(1);
});

Если это не сработает, я понятия не имею.

У меня это не работает. Когда я использую simulate ('press'), у меня такой же сбой, onPress () не является функцией. Странный.

esio 11.03.2018 08:00

Измените refreshData () на refreshData = () =>. Это обязывающая проблема

sfratini 11.03.2018 14:11

Не работает. Мой код работает, но тест - нет ... Когда я изменил код на этот, вы предполагаете, что у меня работает console.info. Была вызвана функция вещи, но у меня проблема с утверждением.

esio 11.03.2018 14:52

См. Мой отредактированный ответ. Вы заявляете, что шпион неправ.

sfratini 11.03.2018 18:40

Я изменил свой код, и теперь у меня есть следующее: pastebin.com/TeRXULbR У меня все еще есть проблема с тестом: «Ожидается, что фиктивная функция будет вызываться один раз, но она вызывалась ноль раз». Я вижу в console.info, что моя функция вызывается, но asertion не работает, потому что похоже, что что-то не так с моей фиктивной функцией.

esio 11.03.2018 19:54

Вместо симуляции используйте второй. Просто выполните onPress (). Также вы правильно добавили опору testID к кнопке?

sfratini 11.03.2018 19:58

Да, у меня нет проблем с вызовом функции, потому что я вижу в журнале «загрузить данные с сервера-заполнителя». У меня проблема с утверждением. К сожалению, onPress () не работает, потому что я получил ошибку: onPress не является функцией.

esio 11.03.2018 20:03

Моделирование не завершится неудачно, если элемент не найден. Сам Enzyme рекомендует использовать onPress. Если вы получили эту ошибку, проблема в селекторе. Он не находит кнопку на снимке или мелком компоненте. Как вы пытаетесь запустить onPress на тесте? И как сейчас твой код? Вы добавили опору testID?

sfratini 11.03.2018 20:08

Хм ... У меня есть селектор testID, как в коде в вопросе. Мой тестовый код находится на pastebin. Выполнение теста Durnig Я вижу Console.log с моим tezy, который я определил в функции refreshData. Думаю, это проф, что моя функция выполняется. Я дважды проверю свой код завтра после работы и вставлю все в pastebin.

esio 11.03.2018 20:27

Это мое приложение и тестовый код: pastebin.com/UK1rctCk В строке 84 я вижу журнал моей консоли из функции.

esio 11.03.2018 22:16

Позвольте нам продолжить обсуждение в чате.

sfratini 12.03.2018 01:44

Да, теперь это будет работать, потому что вы не связали функцию. Попробуйте вместо этого использовать стрелочную функцию, как показано ниже, чтобы вам не хотелось этого делать.

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { Button } from 'react-native';

export default class App extends React.Component {
  refreshData = () => {
    console.info("download data from server placeholder");
  }
  render() {
    return (
      <View style = {styles.container}>
        <Text>Shake your phone to open the developer menu.</Text>
        <Button
          id = "refreshButton"`enter code here`
          onPress = {this.refreshData}
          title = "Refresh"
          color = "#000000"
          accesibilityLabel = "Refresh AQI data"
          testID = "refreshButton"
        />
      </View>
    );
  }
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

Другие вопросы по теме