网站搜索

javascript - 使用 Enzyme 测试 React.createRef()


我有一个组件,在其中使用了新的 React.createRef() API,如何测试 document.activeElement 应该等于当前 ref 组件。

组件 :

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>
}

旧测试(可行):

it('should focus container on mount', () => {
    automatic = mount(<Automatic classes={{}} />, mountContext)

    document.activeElement.should.be.equal(automatic.ref('container'))
})

新的(不起作用):

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

答案#1

已更新为可运行的示例。添加了一个 styled-components 示例。

这是我用 Jest 解决它的方法(使用了不同的断言,但概念是一样的):

// 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)
})
  • 这个想法是获取具有 ref 的元素的实例。
  • 它似乎只在将 MyComponent 包裹在另一个元素中时有效,我使用了 Fragment。

当我使用 **Styled-Components 时遇到了一些麻烦。这是因为它会创建许多额外的元素。尝试使用 console.log(component.debug()) 调试。它会显示 enzyme 渲染的内容。

在调试时,你会看到 Styled-Components 使用了推荐的方式来传递 props。

你可以使用 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)
})
  • 如果你创建了一个高阶组件(HoC),并且需要传递 ref,你也可以使用相同的技巧

答案#2

it('should focus container on mount', () => {
  automatic = mount(<Automatic classes={{}} />, mountContext)

        document.activeElement.should.be.equal(automatic.instance().container.current)
    })