Enzyme Test React.createRef()
10,020
Updated with working examples. Added a styled-components example.
Here's how I solved it with Jest (uses different assertions, but concept is the same):
// setup
const MyComponent = React.forwardRef((props, ref) => (
<div>
<span ref={ref}>some element</span>
</div>
))
// test
it('should contain the forwarded ref in the child span', () => {
const ref = React.createRef()
const component = mount(
<Fragment>
<MyComponent ref={ref} />
</Fragment>,
)
expect(component.find('span').instance()).toEqual(ref.current)
})
- The idea is to get the instance of the element that has the
ref
. - It seems to only work when wrapping
MyComponent
in another element, I usedFragment
.
I ran into some trouble when using **Styled-Components. This is because it creates a number of extra elements. Try debugging with console.log(component.debug())
. It will show you what enzyme renders.
When debugging you'll see that Styled-Components uses the recommended way to forward props.
You can find the right element using the property selector for forwardedRef
:
// setup
const El = styled.div`
color: red;
`
El.displayName = 'El'
const MyComponentWithStyledChild = React.forwardRef((props, ref) => (
<El ref={ref}>some element</El>
))
// test
it('should contain the forwarded ref in a rendered styled-component', () => {
const ref = React.createRef()
const component = mount(
<Fragment>
<MyComponentWithStyledChild ref={ref} />
</Fragment>,
)
// Styled-components sets prop `forwardedRef`
const target = component
.find('[forwardedRef]')
.childAt(0)
.instance()
expect(target).toEqual(ref.current)
})
- You can use the same trick if you created a Higher order Component (HoC) where you need to pass
ref
Related videos on Youtube
Author by
Palaniichuk Dmytro
Updated on June 04, 2022Comments
-
Palaniichuk Dmytro almost 2 years
I have a commponent where I use the new
React.createRef()
api, how to testdocument.activeElement
should be equal current ref commponent.component :
export class Automatic extends Component { componentDidMount = () => this.focusContainer() componentDidUpdate = () => this.focusContainer() container = React.createRef() focusContainer = () => this.container.current.focus() render = () => { return ( <div name='automatic' onKeyPress={this.captureInput} onBlur={() => setTimeout(() => this.focusContainer(), 0)} ref={this.container} tabIndex={0} > ... </div> }
old testing (works):
it('should focus container on mount', () => { automatic = mount(<Automatic classes={{}} />, mountContext) document.activeElement.should.be.equal(automatic.ref('container')) })
new one (doesn't work):
it.only('should focus container on mount', () => { const container = React.createRef() automatic = mount(<Automatic classes={{}} />, mountContext) document.activeElement.should.be.equal(automatic.ref(container.current)) })