在使用中测试超时后的导航(响应导航)调用Effect Hook with Jest

时间:2019-11-05 13:13:57

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

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

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

笑话错误消息

  

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

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

2 个答案:

答案 0 :(得分:0)

it内部”允许您检查某个值是否是我们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);
});

答案 1 :(得分:0)

渲染发生时,不会同步调用

useEffect。在SSR中,根本不调用它。您是否通过放置useEffect来验证测试中是否调用了console.log

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

也值得重新思考测试。似乎正在测试实施细节。