Codesanbox link - includes working component Child2.js and working test Child2.test.js
Child2.js
import React, { useRef } from "react";
export default function Child2() {
const divRef = useRef();
function getDivWidth() {
if (divRef.current) {
console.log(divRef.current);
}
return divRef.current ? divRef.current.offsetWidth : "";
}
function getDivText() {
const divWidth = getDivWidth();
if (divWidth) {
if (divWidth > 100) {
return "ABC";
}
return "123";
}
return "123";
}
return (
<>
<div id="myDiv" ref={divRef}>
{getDivText()}
</div>
<p>Div width is: {getDivWidth()}</p>
</>
);
}
Child2.test.js
import React from "react";
import Enzyme, { shallow } from "enzyme";
import Adapter from "enzyme-adapter-react-16";
import Child2 from "../src/Child2";
Enzyme.configure({ adapter: new Adapter() });
it("div text is ABC when div width is more then 100 ", () => {
const wrapper = shallow(<Child2 />);
expect(wrapper.find("#myDiv").exists()).toBe(true);
expect(wrapper.find("#myDiv").text()).toBe("ABC");
});
it("div text is 123 when div width is less then 100 ", () => {
const wrapper = shallow(<Child2 />);
expect(wrapper.find("#myDiv").exists()).toBe(true);
expect(wrapper.find("#myDiv").text()).toBe("123");
});
When i run the tests, obvisouly the offsetWidth of the div is 0, hence i need to find a way to mock the useRef
to return a div element with width or mock the getDivWidth
function to return a desired number for the width.
How could I achieve that? I have searched for a solution, but I am stuck. There are some examples with class components or using typescript which I have not managed to use.
useLayoutEffect
which will read use thedivref.current.childNodes
to get widths of all theli
elements, how would I change the tests? I tried it and my in the test it never goes inside the function inside theuseLayoutEffect
. In real-life situation I have this scenario, on first render the component has no refs, on second render i have refs and then i use that metadata for operations inside the component. – Pinta