admin管理员组

文章数量:1289869

I would like to test the following class, which uses the React.createRef api.

A quick search didn't reveal any any examples of doing this though. Has anyone had success? How would I go about mocking the ref?

Ideally I'd like to use shallow.

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

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

    this.domRef = React.createRef();
  }

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

  ponentWillUnmount() {
   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>
    );
  }
}

Update

So I can test this using callback refs as follows

 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>
   );
 }
}

Then testing something like

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

I would like to test the following class, which uses the React.createRef api.

A quick search didn't reveal any any examples of doing this though. Has anyone had success? How would I go about mocking the ref?

Ideally I'd like to use shallow.

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

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

    this.domRef = React.createRef();
  }

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

  ponentWillUnmount() {
   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>
    );
  }
}

Update

So I can test this using callback refs as follows

 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>
   );
 }
}

Then testing something like

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

Share Improve this question edited Feb 7, 2019 at 12:01 Tom asked Feb 7, 2019 at 9:44 TomTom 12.7k14 gold badges74 silver badges117 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 8

There's no specific routine for refs to be tested. A ref is just an object with current key.

In case it's accessed early in ponentDidMount, lifecycle hooks need to be disabled for testing. A ponent should be tested that it initially has a ref, then it can be mocked

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

Since a ref is passed to another ponent as a prop, it can be tested that it was provided with correct ref:

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

Then in Wrapper test can be tested that ref current key is assigned with correct object.

本文标签: javascriptTesting the ReactcreateRef api with EnzymeStack Overflow