mrb*_*000 3 unit-testing reactjs jestjs enzyme
我创建了一个React组件,用于加载图像并确定图像是否成功加载.
import React from 'react';
import PropTypes from 'prop-types';
import { LOADING, SUCCESS, ERROR } from '../helpers';
class Image extends React.Component {
static propTypes = {
onError: PropTypes.func,
onLoad: PropTypes.func,
src: PropTypes.string.isRequired,
}
static defaultProps = {
onError: null,
onLoad: null,
}
constructor(props) {
super(props);
this.state = { imageStatus: LOADING };
this.initImage();
}
componentDidMount() {
this.image.onload = this.handleImageLoad;
this.image.onerror = this.handleImageError;
this.image.src = this.props.src;
}
initImage() {
this.image = document.createElement('img');
this.handleImageLoad = this.handleImageLoad.bind(this);
this.handleImageError = this.handleImageError.bind(this);
}
handleImageLoad(ev) {
this.setState({ imageStatus: SUCCESS });
if (this.props.onLoad) this.props.onLoad(ev);
}
handleImageError(ev) {
this.setState({ imageStatus: ERROR });
if (this.props.onError) this.props.onError(ev);
}
render() {
switch (this.state.imageStatus) {
case LOADING:
return this.renderLoading();
case SUCCESS:
return this.renderSuccess();
case ERROR:
return this.renderError();
default:
throw new Error('unknown value for this.state.imageStatus');
}
}
}
export default Image;
Run Code Online (Sandbox Code Playgroud)
我正在尝试使用Jest + Enzyme创建一个测试,以测试图像何时无法加载.
it('should call any passed in onError after an image load error', () => {
const onError = jest.fn();
mount(<Image {...props} src="crap.junk"} onError={onError} />);
expect(onError).toHaveBeenCalled();
});
Run Code Online (Sandbox Code Playgroud)
无论我做什么,Jest总能找到一种成功渲染图像的方法.即使将src设置为false仍会以某种方式呈现图像.有谁知道你怎么能强迫玩笑失败图像负载?
jam*_*oks 21
如果您使用@testing-library/reactimg
,您可以在with上触发错误fireEvent.error
:
const onError = jest.fn();
render(<Image alt="test" src="crap.junk"} onError={onError} />);
fireEvent.error(screen.getByAltText("test"));
expect(onError).toHaveBeenCalled();
Run Code Online (Sandbox Code Playgroud)
由于在幕后,document.createElement('img')
相当于new Image()
,我们可以模拟部分jsdom(由Jest使用)实现,Image
以实现你的目标.
(为简单起见,我已将您的组件重命名为ImageComponent
)
describe('Callbacks', () => {
const LOAD_FAILURE_SRC = 'LOAD_FAILURE_SRC';
const LOAD_SUCCESS_SRC = 'LOAD_SUCCESS_SRC';
beforeAll(() => {
// Mocking Image.prototype.src to call the onload or onerror
// callbacks depending on the src passed to it
Object.defineProperty(global.Image.prototype, 'src', {
// Define the property setter
set(src) {
if (src === LOAD_FAILURE_SRC) {
// Call with setTimeout to simulate async loading
setTimeout(() => this.onerror(new Error('mocked error')));
} else if (src === LOAD_SUCCESS_SRC) {
setTimeout(() => this.onload());
}
},
});
});
it('Calls onError when passed bad src', done => {
const onError = ev => {
expect(ev).toBeInstanceOf(Error);
// Indicate to Jest that the test has finished
done();
};
mount(<ImageComponent onError={onError} src={LOAD_FAILURE_SRC} />);
});
});
Run Code Online (Sandbox Code Playgroud)
在这个jsdom问题中解释了原因onerror
/ onload
从未在浏览器中调用的原因.在同一个问题线程中提供了一个可以影响所有测试的备用修复程序.
你可以嘲笑document.createElement
:
it('should call any passed in onError after an image load error', () => {
const img = {}
global.document.createElement = (type) => type === 'img' ? img : null
const onError = jest.fn();
mount(<Image {...props} src="crap.junk"} onError={onError} />);
img.onload()
expect(onError).toHaveBeenCalled();
});
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5063 次 |
最近记录: |