问题
We have a React component called ScrollContainer than calls a prop function when its content is scrolled to the bottom.
Basically:
componentDidMount() {
const needsToScroll = this.container.clientHeight != this.container.scrollHeight
const { handleUserDidScroll } = this.props
if (needsToScroll) {
this.container.addEventListener('scroll', this.handleScroll)
} else {
handleUserDidScroll()
}
}
componentWillUnmount() {
this.container.removeEventListener('scroll', this.handleScroll)
}
handleScroll() {
const { handleUserDidScroll } = this.props
const node = this.container
if (node.scrollHeight == node.clientHeight + node.scrollTop) {
handleUserDidScroll()
}
}
this.container
is set as follows in the render method:
<div ref={ container => this.container = container }>
...
</div>
I want to test this logic using Jest + Enzyme.
I need a way to force the clientHeight, scrollHeight and scrollTop properties to be values of my choosing for the test scenario.
With mount instead of shallow I can get these values but they are always 0. I have yet to find any way to set them to anything non zero. I can set the container on wrapper.instance().container = { scrollHeight: 0 }
and etc, but this only modifies the test context not the actual component.
Any suggestions would be appreciated!
回答1:
Jest spyOn can be used to mock getter and setter from version 22.1.0+. See jest docs
I used below code to mock implementation of document.documentElement.scrollHeight
const scrollHeightSpy = jest
.spyOn(document.documentElement, 'scrollHeight', 'get')
.mockImplementation(() => 100);
It returns 100 as scrollHeight value.
回答2:
JSDOM doesn't do any actual rendering - it just simulates the DOM structure - so things like element dimensions aren't calculated as you might expect. If you grab dimensions via method calls there are ways to mock these within your test. For example:
beforeEach(() => {
Element.prototype.getBoundingClientRect = jest.fn(() => {
return { width: 100, height: 10, top: 0, left: 0, bottom: 0, right: 0 };
});
});
This obviously won't work in your example. It may be possible to override these properties on the elements and mock changes to them; but I suspect that wouldn't lead to particularly meaningful/useful tests.
See also this thread
来源:https://stackoverflow.com/questions/47823616/mocking-clientheight-and-scrollheight-in-react-enzyme-for-test