React Native/Jest TypeError: Cannot read property 'params' of undefined - testing with jest

React Native/Jest TypeError: Cannot read property 'params' of undefined - testing with jest

我正在尝试在一个应用程序中创建一个测试,这是我的几行代码:

import React, { Component } from 'react';
import {...} from 'react-native';
import jwt_decode from 'jwt-decode';

class CreateProduct extends Component {
constructor(props) {
  super(props);
  this.keyboardHeight = new Animated.Value(0);
  this.imageHeight = new Animated.Value(199);
  this.state = {
    isButtonsHidden: false,
    title: '',
    price: '',
    description: '',
    isDialogVisible: false,
    messageError: '',
  };
}

_goBack = async () => {
  const {state} = this.props.navigation;
  var token = state.params ? state.params.token : undefined;

  this.props.navigation.navigate('MyProducts', {token:token});
}

我想测试导航:

this.props.navigation.navigate('MyProducts', {token:token});

现在这是测试的尝试:

describe('Testing navigation', () =>{

  let wrapper = null
  const spyNavigate = jest.fn()
  const props = {
    navigation:{
        navigate: spyNavigate
    }
  }
  const params = {
      token: 'randomToken'
  }

  beforeEach(() => {
    wrapper = shallow(<CreateProduct {...props}/>)
    wrapper.setState({params: params})
  })

  it('should test navigation', () => {
  wrapper.instance()._goBack(params)
  expect(spyNavigate).toHaveBeenCalled()
  })
})

但我收到 this error。

我假设我传递 const params 的方式有误。你能帮我说说模拟令牌的最佳方法是什么,以及我可以在屏幕中导航的最佳方法吗?

谢谢。

根本原因是你的 _goBackasync。但是你不会等到它在 运行 expect 之前结束。甚至更多:jest 也不会等待 _goBack 完成,所以你甚至不会看到错误

Cannot read property 'params' of undefined

发生这种情况是因为您没有在 navigation.params 中嘲笑 state

要使用异步代码,有 2 different approaches in Jest:从 it() 或 运行 手动返回 Promise done() 回调(它作为第一个参数传递给 it()).

我会选择第二个,因为它允许我们等待直到 goBack 在 运行 之前完成 expect:

describe('Testing navigation', () => {

  let wrapper = null
  const spyNavigate = jest.fn()
  const props = {
    navigation: {
      navigate: spyNavigate,
      state: {}
    }
  }
  const params = {
    token: 'randomToken'
  }

  beforeEach(() => {
    wrapper = shallow(<CreateProduct {...props} />)
    wrapper.setState({ params: params })
  })

  it('should test navigation', async () => {
    await wrapper.instance()._goBack(params)
    expect(spyNavigate).toHaveBeenCalled()
  })
})

或者不使用 async/await 看起来像

  it('should test navigation', () => {
    return wrapper.
        instance()._goBack(params).
        then(() => expect(spyNavigate).toHaveBeenCalled());
  })

看起来很乱

或使用done()回调

  it('should test navigation', (done) => {
      wrapper.
        instance()._goBack(params).
        then(() => expect(spyNavigate).toHaveBeenCalled()).
        then(done);
  })