Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React - Jest - Enzyme: How to mock ref properties

I'm writing test for a component with ref. I'd like to mock the ref element and change some properties but have no idea how to. Any suggestions?

// MyComp.jsx
class MyComp extends React.Component {
  constructor(props) {
    super(props);
    this.getRef = this.getRef.bind(this);
  }
  componentDidMount() {
    this.setState({elmHeight: this.elm.offsetHeight});
  }
  getRef(elm) {
    this.elm = elm;
  }
  render() {
    return <div>
      <span ref={getRef}>
        Stuff inside 
      </span>
    </div>
  }
}

// MyComp.test.jsx
const comp = mount(<MyComp />);
// Since it is not in browser, offsetHeight is 0
// mock ref offsetHeight to be 100 here... How to?
expect(comp.state('elmHeight')).toEqual(100);
like image 233
Xun Yang Avatar asked Dec 11 '18 10:12

Xun Yang


People also ask

How do you mock useRef in Jest Enzyme?

To mock React useRef or a function inside a functional component with enzyme and Jest, we can mock the react module by mocking the useRef hook and getting the rest of the mocked module from the real module. import React, { useRef } from "react"; import { shallow } from "enzyme"; import Child2 from "./"; jest.

Can we pass ref as props in React?

Regular function or class components don't receive the ref argument, and ref is not available in props either. Ref forwarding is not limited to DOM components. You can forward refs to class component instances, too.

Which is better Enzyme or Jest?

Many people choose to use Jest and Enzyme together to test their React web applications. They use Jest as a test runner and assertion library, then use Enzyme to build the tests for their UI. This results in slimmer, cleaner testing code that's also easier to debug when a test breaks.


2 Answers

So here's the solution, according to discussion in https://github.com/airbnb/enzyme/issues/1937

It is possible to monkey-patch the class with a non-arrow function, where "this" keyword is passed to the right scope.

function mockGetRef(ref:any) {
  this.contentRef = {offsetHeight: 100}
}
jest.spyOn(MyComp.prototype, 'getRef').mockImplementationOnce(mockGetRef);
const comp = mount(<MyComp />);
expect(comp.state('contentHeight')).toEqual(100);
like image 196
Xun Yang Avatar answered Oct 19 '22 20:10

Xun Yang


You can mock the ref by using Object.defineProperty. For example:

Object.defineProperty(Element.prototype, 'offsetHeight', {
   value: 100,
   writable: true,
   configurable: true
});
like image 42
Jayshree Wagh Avatar answered Oct 19 '22 19:10

Jayshree Wagh