【问题标题】:Sinon.spy() & jest.spyOn - TypeError: Attempted to wrap undefined property getTableData as functionSinon.spy() & jest.spyOn - TypeError: Attempted to wrap undefined property getTableData as function
【发布时间】:2019-09-06 14:16:20
【问题描述】:

我正在尝试使用 jest “spyOn” 或 sinon “spy” 来监视“getTableData”方法或任何其他类组件方法。一直在得到:

Cannot spy the getTableData property because it is not a function; undefined given instead 与 jest spyOn 和

TypeError: Attempted to wrap undefined property getTableData as function 与 sinon 间谍。

还有我测试的方法被HOC组件包裹的组件,它使用redux连接。然后我尝试在没有 HOC 的情况下导出它,但测试仍然没有出现同样的错误

请注意,const spy = jest.spyOn(wrapper.instance(), "getTableData"); 只有在没有 HOC 的情况下导出组件时才能正常工作!

我已经尝试过的:

const spy = sinon.spy(MonthlyProjectPlan.prototype, 'getTableData');

//const spy = jest.spyOn(MonthlyProjectPlan.prototype, 'getTableData');

    const wrapper = mount(
      //<Provider store={store}>
            <MonthlyProjectPlan {...propsPanel} />
      //</Provider>
    );
export class MonthlyProjectPlan extends React.Component {
  groupBy = (list, keyGetter) => {
    //some secret magic
  };

  getTableData = () => {
    let result = [];
    if (this.props.data) {
      let groupedData = this.groupBy(this.props.data, item => item.commodity);
      // magic
    }
    return result
  };

  getTableColumns = () => {
    let tableData = this.getTableData();
    let columns = [
      {Header: 'Commodities', accessor: 'commodity', width: 300}
    ];

    if (tableData.length > 0) {
      let months = tableData[0].data.map(item => item.year_month_date);
      let monthsColumns = months.map((item, key) => {
        //magic
      });
      columns.push(...monthsColumns)
    }
    return columns
  };

  render() {
    if (!this.props.data)
      return (<LoadingBar/>);
    if (this.props.data.length < 1)
      return (<NoData/>);

    return (
      <div>
        <ReactTable data={this.getTableData()}
                    className="monthly-pipeline__table"
                    columns={this.getTableColumns()}
                    defaultSorted={[{id: "commodity", desc: false}]}
                    showPageSizeOptions={false}
                    showPagination={false}
                    minRows={false}/>

        <div className="monthly-pipeline-help">
          <div className="monthly-pipeline-help__title">
            Monthly Pipeline Shortfalls Percent
          </div>

          <table className="monthly-pipeline-help__table">
            <tbody>
            <tr>
              <td style={{backgroundColor: colors.darkGreen}}>0% - 25%</td>
              <td style={{backgroundColor: colors.yellow}}>26% - 50%</td>
              <td style={{backgroundColor: colors.orange}}>51% - 75%</td>
              <td style={{backgroundColor: colors.red}}>76% - 100%</td>
            </tr>
            </tbody>
          </table>

        </div>
      </div>
    )
  }
}

export default Panel(MonthlyProjectPlan)

下面的测试不起作用

it("should render MonthlyProjectPlan Global component correctly", () => {
    const spy = sinon.spy(MonthlyProjectPlan.prototype, 'getTableData');
    //const spy = jest.spyOn(MonthlyProjectPlan.prototype, 'getTableData');
    const wrapper = mount(
      //<Provider store={store}>
      <MonthlyProjectPlan {...propsPanel} />
      //</Provider>
    );

错误:

“无法窥探 getTableData 属性,因为它不是函数;取而代之的是未定义”,开玩笑 spyOn

"TypeError: Attempted to wrap undefined property getTableData as function" with sinon spy.

这工作正常,但仅适用于没有 HOC 导出的组件

  it("should render MonthlyProjectPlan Global component correctly", () => {
    const wrapper = mount(
      //<Provider store={store}>
      <MonthlyProjectPlan {...propsPanel} />
      //</Provider>
    );
    // const spy = jest.spyOn(wrapper.instance(), "getTableData");
    // wrapper.instance().forceUpdate();
    // expect(spy).toHaveBeenCalled();
    // expect(spy.mock.calls.length).toBe(5);

【问题讨论】:

    标签: javascript reactjs redux jestjs enzyme


    【解决方案1】:

    您将 getTableData 方法定义为class property。因此,原型中没有定义该方法。相反,它是您创建的实例的属性。

    这意味着代码(您提供的代码的简化版本):

    export class MonthlyProjectPlan {
        getTableData = () => {
            let result = [];
            if (this.props.data) {
                let groupedData = this.groupBy(this.props.data, item => item.commodity);
                // magic
            }
            return result
        };
    
        render() {
    
        }
    }
    

    等同于:

    function MonthlyProjectPlan() {
        this.getTableData = function() {
            let result = [];
            if (this.props.data) {
                let groupedData = this.groupBy(this.props.data, item => item.commodity);
                // magic
            }
            return result
        };
    }
    
    MonthlyProjectPlan.prototype.render = function() {};
    

    请注意,getTableData 方法不是在 MonthlyProjectPlan 类的原型中定义的,而是在您创建的类的每个实例上创建一个新方法。 p>

    因此,MonthlyProjectPlan.prototype.getTableData 是未定义的,您无法窥探它。

    【讨论】:

    • 您能解释一下吗:“您将 getTableData 方法定义为类属性。因此,该方法未在原型中定义。相反,它是您创建的实例的属性。 "为什么会发生这种情况,我应该怎么做才能使我的测试正常工作?
    • 我已经编辑了我的答案以进一步解释我的意思。希望对您有所帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-30
    • 2017-12-29
    • 2022-11-20
    • 2021-06-25
    相关资源
    最近更新 更多