我想测试我的React组件是否可以用来FileReader
从<input type="file"/>
元素中导入用户选择文件的内容。我的以下代码显示了一个工作正常且测试失败的组件。
在我的测试中,我尝试使用Blob代替文件,因为Blob也可以被读取FileReader
。那是有效的方法吗?我还怀疑问题的一部分reader.onload
是异步的,我的测试需要考虑到这一点。我需要在某个地方许下诺言吗?或者,我是否可能需要模拟FileReader
使用jest.fn()
?
我真的更喜欢只使用标准的React堆栈。特别是我想使用Jest和Enzyme,而不必使用Jasmine或Sinon等。但是,如果您知道Jest /
Enzyme 无法 完成某些工作,而又 可以 通过其他方式完成,那也可能会有所帮助。
MyComponent.js:
import React from 'react';
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {fileContents: ''};
this.changeHandler = this.changeHandler.bind(this);
}
changeHandler(evt) {
const reader = new FileReader();
reader.onload = () => {
this.setState({fileContents: reader.result});
console.log('file contents:', this.state.fileContents);
};
reader.readAsText(evt.target.files[0]);
}
render() {
return <input type="file" onChange={this.changeHandler}/>;
}
}
export default MyComponent;
MyComponent.test.js:
import React from 'react'; import {shallow} from 'enzyme'; import MyComponent from './MyComponent';
it('should test handler', () => {
const blob = new Blob(['foo'], {type : 'text/plain'});
shallow(<MyComponent/>).find('input')
.simulate('change', { target: { files: [ blob ] } });
expect(this.state('fileContents')).toBe('foo');
});
此答案显示了 如何 使用jest访问代码的所有不同部分。但是,这并不一定意味着 应该 以这种方式测试所有这些部分。
代码被测基本上相同,不同之处在于我已被取代的问题addEventListener('load', ...
为onload = ...
,我已删除了console.log
行:
MyComponent.js :
import React from 'react';
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {fileContents: ''};
this.changeHandler = this.changeHandler.bind(this);
}
changeHandler(evt) {
const reader = new FileReader();
reader.addEventListener('load', () => {
this.setState({fileContents: reader.result});
});
reader.readAsText(evt.target.files[0]);
}
render() {
return <input type="file" onChange={this.changeHandler}/>;
}
}
export default MyComponent;
我相信我已经设法测试了被测代码中的几乎所有内容(注释中指出了一个例外,下面将进一步讨论),其内容如下:
MyComponent.test.js :
import React from 'react';
import {mount} from 'enzyme';
import MyComponent from './temp01';
it('should test handler', () => {
const componentWrapper = mount(<MyComponent/>);
const component = componentWrapper.get(0);
// should the line above use `componentWrapper.instance()` instead?
const fileContents = 'file contents';
const expectedFinalState = {fileContents: fileContents};
const file = new Blob([fileContents], {type : 'text/plain'});
const readAsText = jest.fn();
const addEventListener = jest.fn((_, evtHandler) => { evtHandler(); });
// WARNING: But read the comment by Drenai for a potentially serious
// problem with the above test of `addEventListener`.
const dummyFileReader = {addEventListener, readAsText, result: fileContents};
window.FileReader = jest.fn(() => dummyFileReader);
spyOn(component, 'setState').and.callThrough();
// spyOn(component, 'changeHandler').and.callThrough(); // not yet working
componentWrapper.find('input').simulate('change', {target: {files: [file]}});
expect(FileReader ).toHaveBeenCalled ( );
expect(addEventListener ).toHaveBeenCalledWith('load', jasmine.any(Function));
expect(readAsText ).toHaveBeenCalledWith(file );
expect(component.setState).toHaveBeenCalledWith(expectedFinalState );
expect(component.state ).toEqual (expectedFinalState );
// expect(component.changeHandler).toHaveBeenCalled(); // not yet working
});
我尚未明确测试的一件事是是否changeHandler
被调用。这似乎很容易,但无论出于何种原因,它仍然使我难以理解。它清楚地 已
被html" target="_blank">调用,其他功能嘲笑 之内
就被证实已经被调用但我还没能检查自己是否是所谓的,或者使用jest.fn()
甚至茉莉花的spyOn
问题内容: 给出一个简单的组件: 和测试: 您如何验证表单提交是否将用户带到具有正确查询值的下一页? 我已经尝试过简单地模拟onSubmit处理程序,并至少确认它已被调用,但是由于导致了安全错误。 问题答案: 这实际上很简单,您可以在测试中对它进行浅层渲染时将任何prop传递给该组件,如下所示: 顺便说一句,在内部,您应该致电。 现在,要创建一个模拟(文档中的更多信息),您可以在测试中编写如下代码
我总是在Jest测试中得到“localstorage is not defined”,这很有意义,但我有什么选择呢?撞上砖墙。
问题内容: 我有一个在某些情况下在渲染中返回null的组件: 我想用笑话和酶检查isHidden为true时组件是否为null: 这可行,但是有没有更惯用的方式编写此测试?测试呈现为null的组件是很常见的情况。 问题答案: 而已! 要么:
问题内容: 我正在使用ref为组件编写测试。我想模拟ref元素并更改一些属性,但不知道如何做。有什么建议? 问题答案: 根据https://github.com/airbnb/enzyme/issues/1937中的讨论,这就是解决方案 可以使用非箭头函数对类进行猴子修补,其中“ this”关键字将传递到正确的作用域。
我有一个用 PhpStorm 管理的 TypeScript 项目。所有 ts 文件都被正确识别为打字稿文件,在我的文件类型设置中,我有 文件映射打字稿。 所有的文件?不,一个文件顽固地不会被视为TypeScript文件,而是显示为纯文本。我不知道如何将这个标记为TypeScript文件。 所有<code>*。ts文件旁边有正确的ts图标。这个没有。 当我打开流氓文件时,PhpStom告诉我有该文件
我有一个JavaScript函数,当页面加载时打印10。 这是代码: 上述功能在页面加载时显示“10”。但是它显示在页面的顶部。 但是我想显示“10”作为html表中名为“testtitle2”的行的输入值。