[英]How to mock/spy addEventListener method which is called on ref in ReactJS?
I am doing snapshot testing for one component which has ref on its div.我正在对其 div 上有 ref 的一个组件进行快照测试。 The component looks like -
该组件看起来像 -
import React, { PureComponent } from 'react';
class SearchFlightBuilder extends PureComponent {
scrollRef = React.createRef();
state = {
loading: true,
error: false,
filteredList: [],
pageIndex: 0,
scrollCalled: false,
};
handleScroll = (event) => {
// make sure scroll should be called once
if ((this.scrollRef.current.scrollTop + this.scrollRef.current.clientHeight >= this.scrollRef.current.scrollHeight) && !this.state.scrollCalled) {
this.setState({
pageIndex: this.state.pageIndex + 1
});
this.setState({scrollCalled: true});
}
};
componentDidMount = () => {
this.scrollRef.current.addEventListener('scroll', this.handleScroll);
};
removeScrollEvent = () => {
this.scrollRef.current.removeEventListener('scroll', this.handleScroll);
};
render() {
return (
<div className={c('Search-flight-builder')} ref={this.scrollRef}>
<p>Hello</P
</div>
);
}
};
export default SearchFlightBuilder;
And testing file looks like this -测试文件看起来像这样 -
import React from 'react';
import { shallow, mount, render } from 'enzyme';
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import SearchFlightBuilder from './SearchFlightBuilder';
configure({ adapter: new Adapter() });
const testFlightBuilder = () => <SearchFlightBuilder />;
describe('SearchFlightBuilder', () => {
it('should render correctly', () => {
const component = shallow(<SearchFlightBuilder />);
expect(component).toMatchSnapshot();
});
});
When I am running the tests, I am getting this error - TypeError: Cannot read property 'addEventListener' of null
.当我运行测试时,我收到此错误 -
TypeError: Cannot read property 'addEventListener' of null
。 I tried various approaches, but none of the approach works.我尝试了各种方法,但没有一种方法有效。 Please help me here.
请在这里帮助我。 I am using enzyme library here.
我在这里使用酶库。
Here is my unit test strategy:这是我的单元测试策略:
index.tsx
: index.tsx
:
import React, { PureComponent } from 'react';
class SearchFlightBuilder extends PureComponent {
scrollRef: any = React.createRef();
state = {
loading: true,
error: false,
filteredList: [],
pageIndex: 0,
scrollCalled: false
};
handleScroll = event => {
// make sure scroll should be called once
if (
this.scrollRef.current.scrollTop + this.scrollRef.current.clientHeight >= this.scrollRef.current.scrollHeight &&
!this.state.scrollCalled
) {
this.setState({
pageIndex: this.state.pageIndex + 1
});
this.setState({ scrollCalled: true });
}
};
componentDidMount = () => {
this.scrollRef.current.addEventListener('scroll', this.handleScroll);
};
removeScrollEvent = () => {
this.scrollRef.current.removeEventListener('scroll', this.handleScroll);
};
render() {
return (
<div className="Search-flight-builder" ref={this.scrollRef}>
<p>Hello</p>
</div>
);
}
}
export default SearchFlightBuilder;
Since clientHeight
and scrollHeight
properties are read-only, so they need to be mocked using Object.defineProperty
.由于
clientHeight
和scrollHeight
属性是只读的,因此需要使用Object.defineProperty
来Object.defineProperty
。
index.spec.tsx
: index.spec.tsx
:
import React from 'react';
import { shallow } from 'enzyme';
import SearchFlightBuilder from './';
describe('SearchFlightBuilder', () => {
afterEach(() => {
jest.restoreAllMocks();
});
it('should handle scroll, pageindex + 1', () => {
const mDiv = document.createElement('div');
const events = {};
const addEventListenerSpy = jest.spyOn(mDiv, 'addEventListener').mockImplementation((event, handler) => {
events[event] = handler;
});
mDiv.scrollTop = 1;
Object.defineProperty(mDiv, 'clientHeight', { value: 1 });
Object.defineProperty(mDiv, 'scrollHeight', { value: 1 });
const mRef = { current: mDiv };
const createRefSpy = jest.spyOn(React, 'createRef').mockReturnValueOnce(mRef);
const component = shallow(<SearchFlightBuilder />);
expect(createRefSpy).toBeCalledTimes(1);
expect(addEventListenerSpy).toBeCalledWith('scroll', component.instance()['handleScroll']);
events['scroll']();
expect(component.state('pageIndex')).toBe(1);
expect(component.state('scrollCalled')).toBeTruthy();
});
});
Unit test result with coverage report:带有覆盖率报告的单元测试结果:
PASS src/stackoverflow/57943619/index.spec.tsx (8.618s)
SearchFlightBuilder
✓ should handle scroll, pageindex + 1 (15ms)
-----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
-----------|----------|----------|----------|----------|-------------------|
All files | 94.44 | 85.71 | 80 | 93.75 | |
index.tsx | 94.44 | 85.71 | 80 | 93.75 | 32 |
-----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 9.916s
Source code: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/57943619源代码: https : //github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/57943619
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.