首页 > 解决方案 > 模拟更改输入类型 = 文件后不调用我的模拟函数

问题描述

美好的一天,我需要测试handleChangeLoadFile位于类组件中的函数。我尝试编写一些测试,但它对我不起作用。他的测试让我知道我的模拟函数没有被调用,为什么它没有被调用我无法理解。如果你能帮助我,我将不胜感激。

我的测试:

it('should call handleChangeLoadFile 1 times and complete all mock function', () => {
    let mockFn = jest.fn();
    CreatePostHeader.prototype.handleChangeLoadImage = mockFn;
    const component = mountWithoutStore(<CreatePostHeader {...props} {...propsFunc}/>);
    const createPostComponent = component.find('CreatePostHeader');
    // createPostComponent.instance().handleChangeLoadFile = jest.fn();
    const changeButton = createPostComponent.find('.invisible_input_file').first();
    const file = new File(['dummy content'], 'example.png', {type: 'image/png'});
    changeButton.simulate('change', {target: {files: [file]}});
    expect(mockFn).toHaveBeenCalledTimes(1);
});

调用函数的元素

<input
   type="file"
   accept=".txt, .pdf, .doc, .docx, .odt, .ott, .ods, .ots"
   className="invisible invisible_input_file" ref={this.props.inputHiddenFile}
   onChange={this.handleChangeLoadFile}
/>

我的功能:

handleChangeLoadFile = (event) => {
        for (let i = 0; i < event.target.files.length; i++) {
            const file = event.target.files[i];
            if (validateFile(file)) {
                const typeFile = getUploadFileFormat(file);
                const reader = new FileReader();
                reader.readAsDataURL(file);
                reader.onload = () => {
                    if (_.size(this.state.files) < 5) {
                        this.setState({files: {...this.state.files,
                            [file.name]: {
                                title: file.name,
                                content_type: formatAllowS3[typeFile],
                                document: reader.result
                            }
                        }
                        }, () => this.props.changeItemInState('createPostHeader', this.state));
                    } else {
                        this.props.showNotification('error', this.props.intl.formatMessage({ id: 'createPost.notification.uploadFileCount' }));
                    }
                };
            } else {
                if (file.size > MAX_FILE_SIZE) {
                    this.props.showNotification('error', this.props.intl.formatMessage({ id: 'createPost.notification.uploadFileSize' }));
                } else {
                    this.props.showNotification('error', this.props.intl.formatMessage({ id: 'createPost.notification.uploadFileFormat' }));
                }
            }
        }
    };

标签: reactjsunit-testingjestjsenzyme

解决方案


如果您有一个类组件,请将您的模拟更改为 spy (并记住您不能对箭头函数进行监视):

const mockFn = jest.spyOn(CreatePostHeader.prototype, 'handleChangeLoadImage');

mockImplementation如果您愿意,您当然可以添加您的课程。

如果您有一个功能组件,则必须测试功能的效果,而不是实现本身(甚至更好),例如。

const mockEvent = {target: {files: ['mock']}};
const mockChangeItemInState = jest.fn();

const component = mountWithoutStore(<CreatePostHeader {...props} changeItemInState={mockChangeItemInState}/>);

component.find(/*your input*/).simulate('change', mockEvent);

expect(mockChangeItemInState).toHaveBeenCalledWith(/*something you want*/);

我有点过于简单化了,但你明白了......


推荐阅读