Тестирование вызова навигации (реакции-навигации) после тайм-аута в использовании. Эффект Хук с Jest - PullRequest
0 голосов
/ 05 ноября 2019

У меня есть функциональный компонент, который переходит к другому компоненту после установленного времени ожидания. Это сделано в функции useEffect.

Компонент

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

const Startup: React.FC<> = props => {
  useEffect(() => {
    setTimeout(() => {
      props.navigation.navigate('Signup_Signin');
    }, 3000);
  });

  return (
    <View>
      <Text>Startup View</Text>
    </View>
  );
};

export default Startup;

Вот тест для него

import 'react-native';
import React from 'react';
import { create } from 'react-test-renderer';
import Startup from '../../../src/views/Startup';
// Note: test renderer must be required after react-native.

const createTestProps = (props: Object) => ({
  navigation: {
    navigate: jest.fn(),
  },
  ...props,
});

describe('<Startup />', () => {
  const StartupView = create(<Startup {...createTestProps()} />);
  test('Matches the snapshot', () => {
    expect(StartupView.toJSON()).toMatchSnapshot();
  });
  test('Navigation called with Signup_Signin', () => {
    jest.useFakeTimers();
    jest.advanceTimersByTime(3000);
    expect(StartupView.root.props.navigation.navigate).toHaveBeenCalledWith(
      'Signup_Signin',
    );
  });
});

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

Сообщение об ошибке Jest

● ›Навигация вызывается с Registration_Signin

expect(jest.fn()).toHaveBeenCalledWith(...expected)

Expected: "Signup_Signin"

Number of calls: 0

  25 |     jest.useFakeTimers();
  26 |     jest.advanceTimersByTime(3000);
> 27 |     expect(StartupView.root.props.navigation.navigate).toHaveBeenCalledWith(
     |                                                        ^
  28 |       'Signup_Signin',
  29 |     );
  30 |   });

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

Ответы [ 2 ]

0 голосов
/ 11 ноября 2019

useEffect не вызывается синхронно, когда происходит рендеринг. В ССР это вообще не называется. Вы убедились, что useEffect вызывается вообще в ваших тестах, поставив console.log?

Я бы предложил использовать что-то вроде https://github.com/callstack/react-native-testing-library для тестирования, которое автоматически обрабатывает подобные вещи.

Также стоит переосмыслить тесты. Похоже, он тестирует детали реализации.

0 голосов
/ 05 ноября 2019

it internal 'позволяет вам проверить, является ли определенное значение тем, что мы expected.

Однако функция перемещения по экрану не имеет значения для проверки, поскольку нет результата, возвращаемого значением.

Испытание может быть выполнено следующим образом:

it('Navigation called with Signup_Signin', () => {
  jest.useFakeTimers();
  setTimeout(() => {props.navigation.navigate('Signup_Signin');}, 3000);
  jest.runAllTimers();
});

// OR

it('Navigation called with Signup_Signin', (done) => {
  setTimeout(() => {
    props.navigation.navigate('Signup_Signin');
    done();
  }, 3000);
});
...