This answers shows how to access all of the different parts of the code using jest.
(此答案显示了如何使用jest访问代码的所有不同部分。)
However, it doesn't necessarily mean that one should test all of these parts this way.(但是,这并不一定意味着应该以这种方式测试所有这些部分。)
The code-under-test is essentially the same as in the question except that I have substituted addEventListener('load', ...
for onload = ...
, and I have removed the console.log
line:
(被测代码与问题中的代码基本相同,除了我用addEventListener('load', ...
代替onload = ...
,并且删除了console.log
行:)
MyComponent.js :
(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;
I believe I've managed to test just about everything in the code-under-test (with the one exception noted in the comments and discussed further below) with the following:
(我相信我已经设法通过以下测试了被测代码中的所有内容(注释中指出了一个例外,下面对此进行了进一步讨论):)
MyComponent.test.js :
(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(); });
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
});
The one thing I haven't explicitly tested yet is whether or not changeHandler
was called.
(我尚未明确测试的一件事是是否调用了changeHandler
。)
This seems like it should be easy but for whatever reason it is still eluding me.(这似乎很容易,但无论出于何种原因,它仍然使我难以理解。)
It clearly has been called, as other mocked functions within it are confirmed to have been called but I haven't yet been able to check whether it itself was called, either using jest.fn()
or even Jasmine's spyOn
.(它清楚地被调用,因为在它的其他功能嘲笑被证实已被调用但我还没能检查自己是否被调用,或者使用jest.fn()
甚至茉莉花的spyOn
。)
I have asked this other question on SO to try to address this remaining problem.(我在SO上问了另一个问题 ,以尝试解决这个剩余的问题。)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…