I have looked into similar questions (like this one), but the proposed solutions didn't work for me when using react-testing-library.
I have a component that can receive multiple children. This component will then calculate its own size and its children size, to check how many children it will be able to render. It works fine when I use it in my application.
My problem is that, when rendering this component with react-testing-library, the container of the component is rendered with a 0 height
and width
; so my component will understand that there are no available space to render any child.
I tried to define a custom container inside the tests; tried to force some styling to set width
and height
; but none of that worked.
Is there a way to "fix" that?
const ParentComponent = (props) => {
const [visibleChildren, setVisibleChildren] = useState(0)
const myself = useRef(null)
useEffect(() => {
const componentWidth = myself.current.offsetWidth;
const childrenWidth = myself.current.children.reduce(
// Returns the total children width
)
// Returns the number of children I can display
const childrenAmount = calculateSpace()
setVisibleChildren(childrenAmount)
}, [myself])
// Slice the array of children to display only the right amount
slicedChildren = props.children.slice(0, visibleChildren)
return (
<div ref={myself}>
{slicedChildren}
</div>
)
}
<ParentComponent>
<Child />
<Child />
<Child />
</ParentComponent>
import React from 'react'
import {render} from '@testing-library/react'
import ParentComponent from '../ParentComponent'
test('Render component', () => {
const { getAllByRole } = render(
<ParentComponent>
<Child />
<Child />
<Child />
</ParentComponent>
)
expect(getAllByRole("Child").length).toEqual(3)
})
Added this codesandbox example.
container The containing DOM node of your rendered React Element (rendered using ReactDOM. render ). It's a div . This is a regular DOM node, so you can call container. querySelector etc. to inspect the children.
import { screen } from "@testing-library/react"; ... // get HTML DOM element const spanElement = await screen. queryByTestId('test-span'); // OR // const spanElement = await screen. querySelector('test-span'); // get value from HTML DOM element const spanElementValue = spanElement. getAttribute('value'); ...
I found a way to do this. import App from './App'; import { render, queryByAttribute } from 'react-testing-library'; const getById = queryByAttribute. bind(null, 'id'); const dom = render(<App />); const table = getById(dom. container, 'directory-table');
React Testing Library is a testing utility tool that's built to test the actual DOM tree rendered by React on the browser. The goal of the library is to help you write tests that resemble how a user would use your application.
We can mock that property right on HTMLElement.prototype
:
Object.defineProperties(window.HTMLElement.prototype, {
offsetWidth: {
get: function() { return this.tagName === 'SPAN' ? 100: 500}
}
});
kudos to https://github.com/jsdom/jsdom/issues/135#issuecomment-68191941
Take a look into issue, it has looooong story(since 2011!) but is still opened
Telling the truth, I see mocking offsetWidth
for testing logic to be more reliable. I'd not expect from testing environment to calculate real styles(like offset sizes) all the way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With