Нажмите кнопку React Native Test

Я пытаюсь протестировать вызов метода компонента из элемента React Native Button.

По какой-то причине тест не проходит, если я не сделаю ОБА из этих вещей.

wrapper.find(Button).first().props().onPress();
wrapper.find(Button).first().simulate('press');

Если я закомментирую одну из строк, тест не пройдет, что означает сбой expect(instance.toggleEmailPasswordModal).toHaveBeenCalled();.

Вот моя составляющая:

import React, { Component } from 'react';
import { Button, SafeAreaView, Text } from 'react-native';

import EmailPasswordModal from './EmailPasswordModal/EmailPasswordModal';

class Login extends Component {
  state = {
    emailPasswordModalVisible: false,
  };

  toggleEmailPasswordModal = () => {
    console.info('TOGGLED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
    const { emailPasswordModalVisible } = this.state;
    this.setState({ emailPasswordModalVisible: !emailPasswordModalVisible });
  };

  render() {
    const { emailPasswordModalVisible } = this.state;
    return (
      <SafeAreaView>

        <EmailPasswordModal
          visible = { emailPasswordModalVisible }
          close = { this.toggleEmailPasswordModal }
        />

        <Text>Login Screen!</Text>

        <Button
          onPress = { this.toggleEmailPasswordModal }
          title = "Login with Email and Password"
          color = "#841584"
          accessibilityLabel = "Login with Email and Password"
        />

      </SafeAreaView>
    );
  }
}

export default Login;

Вот мой тест:

import React from 'react';
import ShallowRenderer from 'react-test-renderer/shallow';
import { shallow } from 'enzyme';
import { Button } from 'react-native';

import Login from './Login';

describe('Login Screen', () => {
  describe('Snapshot Tests', () => {
    it('renders the screen with default state', () => {
      const renderer = new ShallowRenderer();
      const props = {};

      renderer.render(<Login { ...props } />);
      expect(renderer.getRenderOutput()).toMatchSnapshot();
    });
  });

  describe('Functional Tests', () => {
    it('calls the toggleEmailPasswordModal method', () => {
      const wrapper = shallow(<Login />);
      const instance = wrapper.instance();
      jest.spyOn(instance, 'toggleEmailPasswordModal');
      wrapper.find(Button).first().props().onPress();
      wrapper.find(Button).first().simulate('press');
      expect(instance.toggleEmailPasswordModal).toHaveBeenCalled();
    });
  });
});

Как ни странно, когда тест запускается, в выходных данных отображается «TOGGLED !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!! " дважды из-за входа в компонент.

Однако, если я поменяю expect на:

expect(instance.toggleEmailPasswordModal).toHaveBeenCalledTimes(1);

тест проходит.

Если я поменяю expect на:

expect(instance.toggleEmailPasswordModal).toHaveBeenCalledTimes(2);

тест не проходит, говорят, что toggleEmailPasswordModal вызывали только 1 раз.

Зачем мне нужны ОБЕИХ из этих линий wrapper.find(Button)...? Я никогда не видел других тестов, требующих их обоих.

Спасибо, Джастин

ОБНОВИТЬ:

Я обновил свой тест следующим образом:

it('calls the toggleEmailPasswordModal method', () => {
  const wrapper = shallow(<Login />);
  const instance = wrapper.instance();
  jest.spyOn(instance, 'toggleEmailPasswordModal');
  wrapper.find(Button).first().props().onPress();
  wrapper.find(Button).first().simulate('press');
  expect(instance.toggleEmailPasswordModal).toHaveBeenCalled();

  // I ADDED THIS SECTION HERE
  expect(instance.state.emailPasswordModalVisible).toBe(true);
});

Тест не проходит, потому что instance.state.emailPasswordModalVisible = false. Это странно, поскольку, по-видимому, называется toggleEmailPasswordModal. Однако, поскольку я подозреваю, что на самом деле он вызывается дважды, я обновляю тест следующим образом:

it('calls the toggleEmailPasswordModal method', () => {
  const wrapper = shallow(<Login />);
  const instance = wrapper.instance();
  jest.spyOn(instance, 'toggleEmailPasswordModal');
  wrapper.find(Button).first().props().onPress();

  // CHANGES START HERE
  // wrapper.find(Button).first().simulate('press');
  // expect(instance.toggleEmailPasswordModal).toHaveBeenCalled();
  expect(instance.state.emailPasswordModalVisible).toBe(true);
});

Угадай, что? Тест проходит нормально. Таким образом, ЯВНО, дважды вызывая функции wrapper.find..., на самом деле дважды вызывает метод toggleEmailPasswordModal. Итак, почему он не может его обнаружить, если я не звоню дважды? Почему он ошибочно полагает, что метод был вызван только один раз?

Умерло ли Create-React-App?
Умерло ли Create-React-App?
В этом документальном фильме React.dev мы исследуем, мертв ли Create React App (CRA) и какое будущее ждет этот популярный фреймворк React.
Освоение React Native: Пошаговое руководство для начинающих
Освоение React Native: Пошаговое руководство для начинающих
React Native - это популярный фреймворк с открытым исходным кодом, используемый для разработки мобильных приложений. Он был разработан компанией...
В чем разница между react native и react ?
В чем разница между react native и react ?
React и React Native - два популярных фреймворка для создания пользовательских интерфейсов, но они предназначены для разных платформ. React - это...
От React к React Native: Руководство для начинающих по разработке мобильных приложений с использованием React
От React к React Native: Руководство для начинающих по разработке мобильных приложений с использованием React
Если вы уже умеете работать с React, создание мобильных приложений для iOS и Android - это новое приключение, в котором вы сможете применить свои...
Хуки React: что это такое и как их использовать
Хуки React: что это такое и как их использовать
Хуки React - это мощная функция библиотеки React, которая позволяет разработчикам использовать состояние и другие возможности React без написания...
3
0
5 006
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Наконец-то у меня есть ответ. Согласно Вызывается функция Jest spyOn, мне нужно сделать instance.forceUpdate(), чтобы прикрепить шпион к компоненту.

it('calls the toggleEmailPasswordModal method', () => {
  const wrapper = shallow(<Login />);
  const instance = wrapper.instance();
  const spy = jest.spyOn(instance, 'toggleEmailPasswordModal');

  // This is added per https://stackoverflow.com/questions/44769404/jest-spyon-function-called/44778519#44778519
  instance.forceUpdate();
  wrapper.find(Button).first().props().onPress();

  expect(spy).toHaveBeenCalledTimes(1);
  expect(instance.state.emailPasswordModalVisible).toBe(true);
});

Теперь тест пройден!

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