我遇到的问题是clientHeightundefined而不是DOM元素的实际高度。此代码可以在浏览器中正常工作。

零件

class MyWidget extends React.Component {
    constructor() {
        super();
        this.state = { contentHeight: 0 };
    }

    componentWillReceiveProps(nextProps) {
        this.setState(() => ({
            contentHeight: nextProps.open ? this.content.firstChild.clientHeight : 0
        }));
    }

    render() {
        const { controlId, open, trigger, children } = this.props;
        return (
            <div>
                <button tabIndex="0" aria-controls={controlId}>
                    { cloneElement(trigger, { open }) }
                </button>
                <div
                    id={controlId}
                    ref={(element) => {
                        this.content = element;
                    }}
                    aria-hidden={open}
                    style={{ maxHeight: this.state.contentHeight }}
                >
                    { cloneElement(children, { open }) }
                </div>
            </div>
        );
    }
}


但是,在安装组件并模拟道具更改时,子clientHeightdiv报告undefined

单元测试

// Arrange
const wrapper = mount(
    <MyWidget trigger={<span>click me</span>} open={false}>
        <div style={{ height: 90, padding: 5 }}>Lorum Ipsum</div>
    </MyWidget>
);

// Act
wrapper.setProps({ open: true });

// Assert
expect(wrapper.children('div').prop('style')).to.have.property('maxHeight', 100);

// Result
AssertionError: expected { maxHeight: undefined } to have a property 'maxHeight' of 100, but got undefined


我并不完全相信酶是造成这种情况的原因,因为感觉它与基础react-dom/test-tools和/或jsdom有关。我在enzyme discussion上添加了注释,因为我希望在进一步调试时有所帮助。

最佳答案

jsdom仅提供DOM-不能直观地呈现您的内容。因此,元素没有宽度或高度。

因为您已经使用maxHeight设置了firstChild.clientHeight,所以该值最终为undefined,因为定义clientHeight需要视觉呈现。

如果您需要验证测试代码中的高度或宽度,则可以尝试使用PhantomJS或无头Chrome-无头浏览器,这些浏览器可以可视地呈现内容。

10-07 21:21