首页 文章

Jest / Enzyme不能模拟类属性

提问于
浏览
0

我目前正在用Jest an Enzyme编写React组件的测试 . 当我必须模拟使用箭头语法编写的类属性函数时,我陷入困境:模拟未应用 .

以下是测试组件的摘录:

class MaClass extends React.Component {
  ...
  componentWillMount () {
    this.getNotifications()
  }
  getNotifications = () => {
    axios.get(window.Routing.generate(
      'api_notifications_get_collection'
    ), {
      headers: {
        'Accept': 'application/json'
      }
    }).then(response => {
      this.setState({
        notifications: response.data
      })
    }).catch(error => {
      console.log('Error : ', error)
    })
  }
  ...
}

以下是测试:

import React from 'react'
import { configure, shallow } from 'enzyme'
import Adapter from 'enzyme-adapter-react-15'

import NotificationsComponent from './NotificationsComponent'

configure({adapter: new Adapter()})

describe('Testing NotificationsComponent', () => {
  /**
   * This should call getNotifications
   */
  test('getNotifications should be called', () => {
    let wrapper = shallow(<NotificationsComponent />)
    const getMock = jest.fn()
    wrapper.instance().getNotifications = getMock
    wrapper.update()
    expect(getMock).toHaveBeenCalled()
  })
})

就阅读而言,这是常规方法的正确方法 . 但似乎用箭头语法编写的类属性函数不能以这种方式进行模拟 .

我的终端抛出一个关于测试组件方法内部的错误:

TypeError: Cannot read property 'generate' of undefined

这意味着模拟不会通过 .

有人会指出我的错误在哪里吗?谢谢 .

2 回答

  • 0

    你正在使用错误的生命周期钩子 . componentWillMount 被称为"inside" shallow(<NotificationsComponent />) . 因此,原始 getNotifications 已被调用 .

    wrapper.update() 强制重新渲染并且不重新装载组件,因此您对模拟的分配无法实现所需的效果 .

  • 0

    问题是没有好的方法来模拟一个箭头函数的类属性 . 到目前为止我找到的最好的解决方法是将类属性移动到类方法并在构造函数中绑定该方法 .

    constructor(props) {
        super(props);
        this.getNotifications = this.getNotifications.bind(this);
    }
    
    getNotifications() {...}
    

    然后在您的测试中,您将能够正确使用 jest.spyOn()

    const spy = jest.spyOn(MaClass.prototype, 'getNotifications');
    

    这是一些额外的信息:https://remarkablemark.org/blog/2018/06/13/spyon-react-class-method/

    希望有所帮助!

相关问题