我们有一个名为ScrollContainer的React组件,而不是在其内容滚动到底部时调用prop函数。
基本上:
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
在render方法中设置如下:
<div ref={ container => this.container = container }>
...
</div>
我想用Jest + Enzyme测试这个逻辑。
我需要一种方法来强制clientHeight,scrollHeight和scrollTop属性成为我为测试场景选择的值。
使用mount而不是浅,我可以获得这些值,但它们始终为0.我还没有找到任何方法将它们设置为非零值。我可以在wrapper.instance().container = { scrollHeight: 0 }
等上设置容器,但这只会修改测试上下文而不是实际组件。
任何建议都将不胜感激!
答案 0 :(得分:5)
JSDOM不进行任何实际渲染 - 它只是模拟DOM结构 - 因此像元素尺寸这样的东西不会像你期望的那样计算。如果您通过方法调用获取维度,则可以在测试中模拟这些维度。例如:
beforeEach(() => {
Element.prototype.getBoundingClientRect = jest.fn(() => {
return { width: 100, height: 10, top: 0, left: 0, bottom: 0, right: 0 };
});
});
这显然不会在你的例子中起作用。可以在元素上覆盖这些属性并模拟对它们的更改;但我怀疑这不会导致特别有意义/有用的测试。
答案 1 :(得分:1)
Jest spyOn可用于模拟版本22.1.0+中的getter和setter。参见jest docs
我使用下面的代码模拟 document.documentElement.scrollHeight
的实现2019-06-05 16:48:35.893 DEBUG 26901 --- [nio-8084-exec-3] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing POST request for [/Accounting/AuthController/test.do]
2019-06-05 16:48:35.893 DEBUG 26901 --- [nio-8084-exec-3] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /AuthController/test.do
2019-06-05 16:48:35.894 DEBUG 26901 --- [nio-8084-exec-3] s.w.s.m.m.a.RequestMappingHandlerMapping : Did not find handler method for [/AuthController/test.do]
2019-06-05 16:48:35.894 DEBUG 26901 --- [nio-8084-exec-3] o.s.w.s.handler.SimpleUrlHandlerMapping : Matching patterns for request [/AuthController/test.do] are [/**]
2019-06-05 16:48:35.894 DEBUG 26901 --- [nio-8084-exec-3] o.s.w.s.handler.SimpleUrlHandlerMapping : URI Template variables for request [/AuthController/test.do] are {}
2019-06-05 16:48:35.894 DEBUG 26901 --- [nio-8084-exec-3] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapping [/AuthController/test.do] to HandlerExecutionChain with handler [ResourceHttpRequestHandler [locations=[ServletContext resource [/], class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@4351bc9]]] and 1 interceptor
2019-06-05 16:48:35.894 DEBUG 26901 --- [nio-8084-exec-3] o.s.web.cors.DefaultCorsProcessor : Skip CORS processing: request is from same origin
2019-06-05 16:48:35.896 DEBUG 26901 --- [nio-8084-exec-3] o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2019-06-05 16:48:35.896 DEBUG 26901 --- [nio-8084-exec-3] o.s.web.servlet.DispatcherServlet : Successfully completed request
2019-06-05 16:48:35.896 ERROR 26901 --- [nio-8084-exec-3] o.s.boot.web.support.ErrorPageFilter : Cannot forward to error page for request [/a/gst25/AuthController/test.do] as the response has already been committed. As a result, the response may have the wrong status code. If your application is running on WebSphere Application Server you may be able to resolve this problem by setting com.ibm.ws.webcontainer.invokeFlushAfterService to false
它返回100作为scrollHeight值。
答案 2 :(得分:0)
简化的解决方案只需要模拟 useRef
或 createRef
,因为被测组件取决于 useRef
的返回值:
import { useRef } from 'react';
jest.mock('react', () => ({
...jest.requireActual('react'),
useRef: jest.fn(),
}));
test('test ref', () => {
useRef.mockReturnValue({
// insert required properties here
});
// do assertions as normal
});