3

I have a component that contains input that has assigned function to ref and I try to write test for it:

 <input
   id="input-element"
   type="checkbox"
   checked={isChecked}
   ref={(input) => {
       if (input) {
           input.indeterminate = true;
       }
   }}
   className="checkbox" />

And my question is how check in test if the input indeterminate is set to true. Documentation https://airbnb.io/enzyme/docs/api/ReactWrapper/ref.html didn't help me because there are only very simple and useless examples.

I tried to test it so:

const wrapper = shallow(<MyComponent {...props}/>);
expect(wrapper.find('#input-element').prop('indeterminate')).toBeTruthy();

But wrapper.find('#input-element').prop('indeterminate') returns me undefined

Arun Yokesh
  • 1,346
  • 17
  • 19
user
  • 4,410
  • 16
  • 57
  • 83

4 Answers4

5

If all you care about is testing the ref setting callback and not the ref component itself, I've figured out a way to do this with a shallow rendered component by mocking the ref:

const mockRef = {};
const wrapper = shallow(<MyComponent/>);
const inputElement = wrapper.find('#input-element');
inputElement.getElement().ref(mockRef)
expect(mockRef.indeterminate).toEqual(true);
Eliot
  • 5,450
  • 3
  • 32
  • 30
3

From Enzyme github:

You might have noticed the ShallowRenderer doesn't have docs for a ref() mehthod, while the MounedRenderer does. If you want to test refs you have to mount.

I believe the reason is that shallow rendering does not maintain an internal instance and therefore it can't hold a ref. That is the purpose of shallow rendering. Even FB ReactTestUtils shallowRendering doesn't work with refs.

https://github.com/airbnb/enzyme/issues/316

You need to use mount instead of shallowMount.

check here also:

https://airbnb.io/enzyme/docs/api/ReactWrapper/ref.html

azrahel
  • 1,143
  • 2
  • 13
  • 31
1

According to the React docs section on Callback Refs, "React will call the ref callback with the DOM element when the component mounts".

shallow does not do a full DOM render so the component is never mounted and the Callback Ref is never called. To ensure the Callback Ref is called you will need to do a full DOM render with mount.

Starting with v2.7 Enzyme provides ReactWrapper.getDOMNode as part of the Full DOM Rendering API.

You can use mount in combination with ReactWrapper.getDOMNode to get access to the DOM node and test for indeterminate like this:

const wrapper = mount(<MyComponent {...props} />);
expect(wrapper.find('#input-element').first().getDOMNode().indeterminate).toBeTruthy();  // SUCCESS
Brian Adams
  • 43,011
  • 9
  • 113
  • 111
  • is there any way for testing the useLayoutEffect, tried using shallow and mount didnt worked any suggestions on this ? https://stackoverflow.com/questions/59157804/testing-uselayouteffect-using-jest-and-enzyme-for-window-resize?noredirect=1#comment104541097_59157804 – Learner Dec 04 '19 at 04:18
0

May Be you can try like this: when you wrote more complex code then you need to write complex tests also, I hope this helps you.

handle = (e) => {
   // indeterminate = true;
   // whatever you what to do
}

<input
   id="input-element"
   type="checkbox"
   checked={isChecked}
   ref="inputRef"
   onChange={() => this.handle()}
   className="checkbox">

Testing code

const wrapper = shallow(<MyComponent {...props}/>);
const inputElement = wrapper.find('#input-element').prop();
expect(inputElement.ref).toEqual("inputRef");
inputElement.onClick();
// your condition I'm not sure
// expect(indeterminate).toBeTruthy();
Arun Yokesh
  • 1,346
  • 17
  • 19