【问题标题】:Testing navigate (react-navigation) call after timeout in useEffect Hook with Jest在使用 Jest 的 useEffect Hook 超时后测试导航(react-navigation)调用
【发布时间】:2019-11-05 13:13:57
【问题描述】:

我有一个功能组件,它在设置的超时后导航到另一个组件。这是在 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',
    );
  });
});

我首先测试该组件是否与它的快照匹配,该快照通过时没有问题。 然后我创建一个假计时器并将其推进到与组件中设置的计时器相同的计时器。然后我可以验证是否调用了 navigate 道具。

开玩笑错误消息

● › 使用 Signup_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 |   });

似乎从未调用过该道具。我已经检查了我的应用程序,并且导航实际上已经完成。我猜问题出在我描述测试的方式上。

【问题讨论】:

    标签: reactjs react-native jestjs react-navigation react-hooks


    【解决方案1】:

    itinternal' 允许您检查某个值是否是我们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);
    });
    

    【讨论】:

    • 我不明白为什么我必须在测试中手动执行导航功能,因为我想验证它是否在组件挂钩中自动执行。
    【解决方案2】:

    useEffect 在渲染发生时不会被同步调用。在 SSR 中,根本不调用它。您是否通过放置 console.log 验证了在您的测试中是否调用了 useEffect

    我建议使用 https://github.com/callstack/react-native-testing-library 之类的东西来进行自动处理此类事情的测试。

    也值得重新考虑测试。好像是在测试实现细节。

    【讨论】:

      猜你喜欢
      • 2021-01-07
      • 2020-01-18
      • 2018-02-15
      • 2021-07-26
      • 2022-01-26
      • 2021-04-16
      • 2018-11-28
      • 2019-08-18
      • 2023-03-18
      相关资源
      最近更新 更多