user
user

Reputation: 4830

React/enzyme - How to test reference function

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

Upvotes: 3

Views: 5433

Answers (4)

Eliot
Eliot

Reputation: 5659

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

Upvotes: 5

Brian Adams
Brian Adams

Reputation: 45810

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

Upvotes: 1

Arun Yokesh
Arun Yokesh

Reputation: 1354

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

Upvotes: 0

azrahel
azrahel

Reputation: 1213

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

Upvotes: 3

Related Questions