【问题标题】:Testing the `React.createRef` api with Enzyme使用 Enzyme 测试 `React.createRef` api
【发布时间】:2019-07-01 09:30:48
【问题描述】:

我想测试以下使用React.createRef api 的类。

快速搜索并没有发现任何这样做的例子。有没有人成功过?我将如何去嘲笑裁判?

理想情况下,我想使用shallow

class Main extends React.Component<Props, State> {

  constructor(props) {
    super(props);
    this.state = {
      contentY: 0,
    };

    this.domRef = React.createRef();
  }

  componentDidMount() {
    window.addEventListener('scroll', this.handleScroll);
    handleScroll();
  }

  componentWillUnmount() {
   window.removeEventListener('scroll', this.handleScroll);
  }

  handleScroll = () => {
    const el = this.domRef.current;
    const contentY = el.offsetTop;
    this.setState({ contentY });
  };

  render() {
    return (
      <Wrapper innerRef={this.domRef}>
        <MainRender contentY={this.state.contentY} {...this.props} />
      </Wrapper>
    );
  }
}

更新

所以我可以使用如下回调引用来测试它

 setRef = (ref) => {
   this.domRef = ref;
 }

 handleScroll = () => {
   const el = this.domRef;
   if (el) {
     const contentY = el.offsetTop;
     this.setState({ contentY });
   }
 };

 render() {
   return (
     <Wrapper ref={this.setRef}>
       <MainRender contentY={this.state.contentY} {...this.props} />
     </Wrapper>
   );
 }
}

然后测试类似的东西

it("adds an event listener and sets currentY to offsetTop", () => {
    window.addEventListener = jest.fn();
    const component = shallow(<ScrollLis />)
    const mockRef = { offsetTop: 100 };
    component.instance().setRef(mockRef);
    component.instance().componentDidMount();
    expect(window.addEventListener).toBeCalled();
    component.update();
    const mainRender = component.find(MainRender);
    expect(mainRender.props().contentY).toBe(mockRef.offsetTop);
  }); 

【问题讨论】:

    标签: javascript reactjs jestjs enzyme


    【解决方案1】:

    对于要测试的 refs 没有特定的例程。 ref 只是一个带有current 键的对象。

    如果它在 componentDidMount 早期被访问,则需要禁用生命周期挂钩以进行测试。一个组件应该被测试它最初有一个引用,然后它可以被模拟

    const wrapper = shallow(<Comp/>, { disableLifecycleMethods: true });
    expect(wrapper.instance().domRef).toEqual({ current: null });
    wrapper.instance().domRef.current = mockRef;
    wrapper.instance().componentDidMount();
    

    由于 ref 作为 prop 传递给另一个组件,因此可以测试它是否提供了正确的 ref:

    expect(wrapper.find(Wrapper).dive().props().innerRef).toBe(wrapper.instance().domRef);
    

    然后在Wrapper 测试中可以测试 ref current 键被分配了正确的对象。

    【讨论】:

    • 好吧,在我的例子中Wrapper 只是一个样式化的组件div。我需要给this.domRef.current 一个offsetTop 以阻止它出错。你知道我会怎么做吗?
    • 我的意思是 Wrapper 像 const ref = { current: null }; const wrapperWrapper = shallow(&lt;Wrapper innerRef={ref}; expect(ref.current).toBe(wrapperWrapper.instance()) 一样经过测试。我不确定 offsetTop 涉及到哪里。
    • React 确保在调用 handleScroll 时,this.domRef.current 引用 dom 节点,因此可以访问我使用 offsetTop 的所有道具。它如何模拟我所追求的React.createRef()设置的dom节点
    • 在我测试生命周期方法时,const contentY = el.offsetTop; 这一行出现上述错误
    • 这个问题没有说明为什么会触发滚动事件。但是 DOM 事件不应该首先在单元测试中触发,尤其是像滚动这样的全局事件。如果需要,存根 addEventListener 和 removeEventListener。无论如何,您需要在 handleScroll 测试中使用具有 offsetTop 属性的对象来模拟 ref。
    猜你喜欢
    • 2020-08-10
    • 2020-08-07
    • 2017-11-01
    • 2018-07-11
    • 2018-07-23
    • 2019-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多