【问题标题】:How to test for a react component method been called by another method如何测试反应组件方法被另一种方法调用
【发布时间】:2023-03-12 03:41:02
【问题描述】:

我有一个类,它在初始化时调用另一个方法,该方法调用另一个名为 pan 的方法。我正在尝试测试是否调用了 pan 方法。这个类比这更复杂,但我想要测试的只是 pan 被调用了。

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.pan = this.pan.bind(this);
  }

  componentDidMount() {
    initExternals();
  }

  initExternals() {
    .. bla bla
   this.pan();
  }

  pan() {
   console.log('Function was called');
  }

}

这是我的测试课

test('component should call initMap', () => {
  const spy = jest.spyOn(WhereWeAreMap.prototype, 'pan');
  const component = mount(<WhereWeAreMap />);
  expect(spy).toHaveBeenCalled();
});

I have also tried.
test('component should call initMap', () => {
  const component = mount(<WhereWeAreMap />);
  const spy = jest.spyOn(component.instance(), 'pan');
  wrapper.instance().forceUpdate();
  expect(spy).toHaveBeenCalled();
});

我的测试出了什么问题,因为它无法测试组件方法 pan 被调用 expect(spy).toHaveBeenCalled()。日志显示它被调用,但我的测试显示不同。

预期的模拟函数已被调用,但未调用。

【问题讨论】:

  • 你的test 函数应该做什么?你的组件在哪里渲染?
  • 它应该检查 pan 方法实际上是从 MyComponent 内部调用的。 MyComponent 被渲染为另一个组件的子组件。

标签: reactjs jestjs enzyme


【解决方案1】:

第一种测试方法绝对适合我,很快将其添加到我运行 ATM 的测试中并且很好:

  it('adds the correct scroll blocking class to document.body', () => {
    const spy = jest.spyOn(BlockUI.prototype, 'foo');
    const instance = mount(<BlockUI />).instance();
    // some suggest you need to do this but works without it.
    // instance.forceUpdate();

    const body = instance.document.body;
    expect(body.className).toMatchSnapshot();
    expect(spy).toHaveBeenCalled();
  });

BlockUI.prototype.foo 向实例添加了对document.body 的引用,并向实例添加了一个需要在卸载时删除的类。

上面的设置很好:

"enzyme": "3.7.0",
"enzyme-adapter-react-16": "1.7.1",
"enzyme-to-json": "3.3.4",
"jest": "23.6.0",

以前我很难让它在没有酶或旧版本的情况下工作,但现在没问题。

异步内容存在可能导致问题的异常 - 我建议不要使用间谍,而是检查要确保调用的方法的结果,无论是什么。在酶中不使用浅渲染器时,保证调用生命周期方法

您正在改变构造函数中实例上的pan 方法,方法是从原型中保存它的本地绑定副本 - 但它仍应调用原型并且间谍应捕获它。我希望您使用的是旧版本的东西。

【讨论】:

    【解决方案2】:
       class MyComponent extends React.Component {
    
          constructor(props) {
            super(props);
            this.pan = this.pan.bind(this);
    
          }
    
          componentDidMount() {
            this.initExternals();
          }
    
          initExternals() {
           this.pan();
          }
    
          pan() {
           console.log('Function was called');
          }
        }
    

    在componentDidMount方法中应用MyComponent的Scope

    initExternals 应该是 this.initExternals

    我对窗口对象的意图是说其他作用域可以绑定到函数

    例如,如果函数是在窗口范围内调用的,即 window.initExternals,那么 this 关键字将引用窗口

    那就是 window.pan

    【讨论】:

    • window.pan? o_O 你真的需要更好地阅读和理解范围。
    • @DimitarChristoff 是的,你是对的,我没有教过那个人,你看起来是个好人,一个超级好人,我拼错了吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-30
    • 2015-12-15
    • 2017-05-28
    • 1970-01-01
    • 2021-04-18
    相关资源
    最近更新 更多