简体   繁体   English

为什么在测试中我的子组件上的道具未更新?

[英]Why is the prop not being updated on my child component in my test?

Below are the relevant parts of my component to the test. 以下是测试组件的相关部分。 I am trying to test my component by opening the Snackbar and then clicking the close button in the SnackbarContentWrapper component, which is in the 3rd level of nesting. 我试图通过打开Snackbar ,然后单击SnackbarContentWrapper组件中的关闭按钮来测试我的组件,该组件处于第三层嵌套中。

onSuccess() {
    this.setState({
        snackbarOpen: true,
        snackbarVariant: 'success',
        snackbarMsg: 'A super useful message'
    })
}

render() {
    return (
        <>
            ...some stuff...

            <MyForm
                beginAjaxCall={this.beginAjaxCall}
                endAjaxCall={this.endAjaxCall}
                onSuccess={this.onSuccess}
                onError={this.onError}
                onSave={save}
            />
            <Snackbar
                anchorOrigin={{
                    vertical: 'bottom',
                    horizontal: 'left'
                }}
                open={this.state.snackbarOpen}
                autoHideDuration={6000}
                onClose={this.onSnackbarClose}
            >
                <SnackbarContentWrapper
                    onClose={this.onSnackbarClose}
                    variant={this.state.snackbarVariant}
                    message={this.state.snackbarMsg}
                />
            </Snackbar>
        </>
    )
}

This is my test: 这是我的测试:

    it('state reflects closing the snackbar', () => {
        const page = mount(<MyPage/>),
            form = page.find(MyForm),
            snackbar = page.find(Snackbar),
            snackbarContent = snackbar.find(SnackbarContentWrapper)

        // test snackbar is closed at start (this passes)
        expect(page.state().snackBarOpen).toBeFalsy()

        // call the prop on form which calls the class method, onSuccess
        form.props().onSuccess()

        // (this passes)
        expect(page.state().snackbarOpen).toBeTruthy()

        page.update()
        snackbar.update()

        console.log(page.state().snackbarOpen) // true
        console.log(snackbar.props()) // false - should match state of page

        const button = snackbarContent.find('button')

        // crashes here
        button.simulate('click')

        expect(page.state().snackbarOpen).toBeFalsy()
    })

snackbar.props().open is set to false, even though page.state().snackbarOpen is set to true. snackbar.props().open设置为false,即使page.state().snackbarOpen设置为true。

Another oddity is that I'm getting an error, Method “simulate” is only meant to be run on a single node. 另一个奇怪的是,我遇到了一个错误, 方法“模拟”仅旨在在单个节点上运行。 0 found instead. 找到0个。 when trying to simulate the button click. 尝试模拟按钮单击时。 However, when I log the html of snackbar , I can see the html generated from the child snackbarContent , including the button. 但是,当我记录snackbar的html时,我可以看到从子snackbarContent生成的html,包括按钮。

I've been working on this for several hours and I've done things similar to it to simulate button clicks successfully, so I'm at a loss here. 我已经为此工作了几个小时,并且我已经做了类似的事情来成功模拟按钮点击,所以在这里我很茫然。

I figured this out after stumbling across an innocuous comment in a github post. 我在github帖子中绊倒无害评论后才想到了这一点。 The issue is that the child components relying on the re-render have to be found ( .find() ed?) after .update() , not before. 问题在于,必须在.find()之后 .update()不是之前找到依赖于重新渲染的子组件( .find() ed?)。 They are immutable as of v3, so the variables won't be current if set at the top of the test as I have done. 从v3开始,它们是不可变的,因此,如果像我一样在测试的顶部进行设置,这些变量将不是当前变量。 So, the fixed test is: 因此,固定测试为:

it('state reflects closing the snackbar', () => {
    const page = mount(<MyPage/>),
        form = page.find(MyForm)

    // test snackbar is closed at start
    expect(page.state().snackBarOpen).toBeFalsy()

    // call the prop on form
    form.props().onSuccess()

    // on success, the snackbar should pop open
    expect(page.state().snackbarOpen).toBeTruthy()

    page.update()

    // **must grab components after** the update
    // to reflect their current state
    const snackbar = page.find(Snackbar),
        snackbarContent = snackbar.find(SnackbarContentWrapper),
        button = snackbarContent.find('button')

    // close the snackbar
    button.simulate('click')

    // state and prop are set back to closed
    expect(page.state().snackbarOpen).toBeFalsy()
})

After that, my assertions were good to go with the current state/props. 在那之后,我的断言很好地支持当前状态/道具。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM