如何在玩笑中使用模拟更改来测试 FileReader onload? [英] How to test FileReader onload using simulate change in jest?

查看:22
本文介绍了如何在玩笑中使用模拟更改来测试 FileReader onload?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

SimpleDialog.jsx

const [imagePreview, setImagePreview] = React.useState(null);const handleChangeImage = 事件 =>{let reader = new FileReader();让文件 = event.target.files[0];reader.onload = 事件 =>{控制台日志(事件);setImagePreview(event.target.result);};reader.readAsDataURL(文件);};返回 (<div><输入接受=图像/*"id="包含按钮文件"多类型=文件"样式={{ 显示:'无' }}onChange={handleChangeImage}/><img id="preview" src={imagePreview}/>

);

SimpleDialog.test.js

it('should change image src', () => {常量事件 = {目标: {文件:[{name: 'image.png',大小:50000,类型:'图像/png'}]}};让间谍 = 开玩笑.spyOn(FileReader.prototype, 'onload').mockImplementation(() => null);wrapper.find('input[type="file"]').simulate('change', event);期望(间谍).toHaveBeenCalled();期望(wrapper.find('#preview').prop('src')).not.toBeNull();});

运行测试时,它给了我错误TypeError: Illegal invocation.

谁能帮我做这个单元测试?我只想模拟图像的 src 是否有价值.

解决方案

错误原因是onload被定义为属性描述符并赋值给FileReader.prototype 不支持由 spyOn 完成的操作.

没有理由模拟 onload 因为它是在测试代码中分配的,需要进行测试.

直接的方法是不修补 JSDOM FileReader 实现,而是完全存根:

jest.spyOn(global, 'FileReader').mockImplementation(function () {this.readAsDataURL = jest.fn();});wrapper.find('input[type="file"]').simulate('change', event);让读者 = FileReader.mock.instances[0];期望(reader.readAsDataURL).toHaveBeenCalledWith(...);期望(reader.onload).toBe(expect.any(函数));期望(wrapper.find('#preview').prop('src')).toBeNull();reader.onload({ target: { result: 'foo' } });期望(wrapper.find('#preview').prop('src')).toBe('foo');

SimpleDialog.jsx

const [imagePreview, setImagePreview] = React.useState(null);

const handleChangeImage = event => {
    let reader = new FileReader();
    let file = event.target.files[0];

    reader.onload = event => {
        console.log(event);

        setImagePreview(event.target.result);
    };

    reader.readAsDataURL(file);
};

return (
    <div>
        <input
            accept="image/*"
            id="contained-button-file"
            multiple
            type="file"
            style={{ display: 'none' }}
            onChange={handleChangeImage}
        />

        <img id="preview" src={imagePreview} />
    </div>
);

SimpleDialog.test.js

it('should change image src', () => {
    const event = {
        target: {
            files: [
                {
                    name: 'image.png',
                    size: 50000,
                    type: 'image/png'
                }
            ]
        }
    };

    let spy = jest
        .spyOn(FileReader.prototype, 'onload')
        .mockImplementation(() => null);

    wrapper.find('input[type="file"]').simulate('change', event);

    expect(spy).toHaveBeenCalled();

    expect(wrapper.find('#preview').prop('src')).not.toBeNull();
});

When running the test it gives me the error TypeError: Illegal invocation.

Anyone who can help me with this unit test? I Just want to simulate on change if the src of an image has value or not.

解决方案

The cause of the error is that onload is defined as property descriptor and assigning it to FileReader.prototype which is done by spyOn isn't supported.

There's no reason to mock onload because it's assigned in tested code and needs to be tested.

The straightforward way is to not patch JSDOM FileReader implementation but stub it entirely:

jest.spyOn(global, 'FileReader').mockImplementation(function () {
    this.readAsDataURL = jest.fn();
});

wrapper.find('input[type="file"]').simulate('change', event);


let reader = FileReader.mock.instances[0];
expect(reader.readAsDataURL).toHaveBeenCalledWith(...);
expect(reader.onload).toBe(expect.any(Function));

expect(wrapper.find('#preview').prop('src')).toBeNull();

reader.onload({ target: { result: 'foo' } });

expect(wrapper.find('#preview').prop('src')).toBe('foo');

这篇关于如何在玩笑中使用模拟更改来测试 FileReader onload?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆