我有一个组件触发窗口事件的组件实例方法(调整大小和滚动)。我试图窥探事件处理程序,但间谍永远不会被调用。
这是我的组件:
class PopOverContainer extends PureComponent {
static propTypes = {
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node),
PropTypes.node
]),
transitionState: PropTypes.string,
animationTiming: PropTypes.object,
anchorEl: PropTypes.object,
hAlign: PropTypes.oneOf(['left', 'right'])
}
constructor(props) {
super(props)
this.state = {
mounted: false
}
this.setRef = this.setRef.bind(this)
this.forceReposition = this.forceReposition.bind(this)
}
componentDidMount() {
window.addEventListener('resize', this.forceReposition)
window.addEventListener('scroll', this.forceReposition)
// Don't normally do this! We need to do this here since our animate in
// does not work properly if the default styles are not in the DOM before we
// transition them
setTimeout(() => this.setState({ mounted: true }), 0)
}
componentWillUnmount() {
window.removeEventListener('resize', this.forceReposition)
window.removeEventListener('scroll', this.forceReposition)
}
getAnchorPosition() {
if (!this.state.mounted) return {}
if (!this.props.anchorEl) return {}
const { anchorEl, hAlign } = this.props
const popOverEl = this.popOverEl
const rect = anchorEl.getBoundingClientRect()
const calcHOffset = () => {
if (hAlign === 'right') {
return rect.left + (anchorEl.offsetWidth - popOverEl.offsetWidth)
}
return rect.left
}
const pos = {
top: rect.top + anchorEl.offsetHeight,
left: calcHOffset()
}
return pos
}
forceReposition() {
this.forceUpdate()
}
setRef(el) {
this.popOverEl = el
}
render() {
const {
transitionState,
animationTiming,
children,
...styledProps
} = this.props
return (
<StyledPopOver
innerRef={this.setRef}
transitionState={transitionState}
animationTiming={animationTiming}
style={this.getAnchorPosition()}
{...styledProps}
>
{children}
</StyledPopOver>
)
}
}
这是测试:
it('should force an update on scroll', async () => {
const wrapper = mount(
<PopOverContainer anchorEl={anchorEl}>
<span>Hi</span>
</PopOverContainer>
)
await new Promise(resolve => setTimeout(resolve, 2))
const instance = wrapper.instance()
const forceRepositionSpy = jest.spyOn(instance, 'forceReposition')
wrapper.update()
window.dispatchEvent(new Event('resize'))
expect(forceRepositionSpy).toHaveBeenCalled()
})
以下是我得到的测试结果:
expect(jest.fn()).toHaveBeenCalled()
Expected mock function to have been called.
我确实在组件中加入了一些奇怪的东西,因为它有一些动画需要在安装组件后的下一个刻度开始。 (注意setTimeout(() => this.setState({ mounted: true }), 0)
)
我不知道这与我所看到的有什么关系,但最后,我的spyOn(实例,'forceReposition')永远不会被调用,即使我已经添加了控制台日志并且可以看到事件处理程序this.forceReposition
确实在实例中被调用。