在测试 React 组件 onClick 时监视功能检查
Spying on function checking when testing React component onClick
我有一个父组件和一个子组件。
父组件:
const ParentComponent = () => {
const click_button = (role) => {
document.getElementById(role).innerHTML = role;
}
return (
<div>
<ChildButton id= 'button_child' name='button_1' onClick={() => {
click_button('role_1')
}}/>
<div>
<p id="role_1"/>
<p id="role_2"/>
<p id="role_3"/>
</div>
</div>
)
}
export default ParentComponent;
子组件
import React from 'react';
const ChildButton = (props) => {
return (
<React.Fragment>
<button onClick={props.onClick}>{props.name}</button>
</React.Fragment>
)
}
export default ChildButton;
ParentComponent
的测试之一:
it('buttons should render correctly', () => {
const wrapper shallow(<ParentComponent/>);
const instance = wrapper.instance();
jest.spyOn(instance, 'click_button');
expect(instance.click_button).toHaveBeenCalledTimes(0);
wrapper.find('#button_child').simulate('click');
expect(instance.click_button).toHaveBeenCalledTimes(1);
});
我的应用程序使用 jest 和 enzyme 进行测试。示例中的点击功能需要在 ParentComponent 中进行测试。但是,当我尝试访问该按钮时,测试失败了,这是因为该按钮位于 childButton
组件中。
所以基本上问题是如何测试 ParentComponent
中的 click_button
函数?
上面的例子实例是空的,酶文档说会是这种情况。现在我看到个人绕过这个的唯一方法是 'watching' 控制台日志,这对我来说似乎有点 hacky?
我正在努力坚持使用 Enzyme 和 Jest,因为这是我编写单元测试的内容,我希望我的集成测试可以效仿。
感谢您的帮助。
测试组件的行为而不是实现细节。使用 enzyme
的 mount()
函数一起测试父子组件。 React 功能组件没有实例,但 class 个组件有实例。
例如
parent.jsx
:
import ChildButton from './child';
const ParentComponent = () => {
const click_button = (role) => {
document.getElementById(role).innerHTML = role;
};
return (
<div>
<ChildButton
id="button_child"
name="button_1"
onClick={() => {
click_button('role_1');
}}
/>
<div>
<p id="role_1" />
<p id="role_2" />
<p id="role_3" />
</div>
</div>
);
};
export default ParentComponent;
child.jsx
:
import React from 'react';
const ChildButton = (props) => {
return (
<React.Fragment>
<button onClick={props.onClick}>{props.name}</button>
</React.Fragment>
);
};
export default ChildButton;
parent.test.jsx
:
import React from 'react';
import ParentComponent from './parent';
import { mount } from 'enzyme';
describe('66698493', () => {
beforeAll(() => {
const div = document.createElement('div');
div.setAttribute('id', 'container');
document.body.appendChild(div);
});
it('should change the inner HTML', () => {
const wrapper = mount(<ParentComponent />, { attachTo: document.getElementById('container') });
expect(document.getElementById('role_1').innerHTML).toEqual('');
wrapper.find('button').simulate('click');
expect(document.getElementById('role_1').innerHTML).toEqual('role_1');
});
});
测试结果:
PASS examples/66698493/parent.test.jsx
66698493
✓ should change the inner HTML (46 ms)
------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
------------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
child.jsx | 100 | 100 | 100 | 100 |
parent.jsx | 100 | 100 | 100 | 100 |
------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 6.067 s
jest.config.js
:
module.exports = {
preset: 'ts-jest/presets/js-with-ts',
testEnvironment: 'enzyme',
setupFilesAfterEnv: [
'jest-enzyme',
],
setupFiles: ['./jest.setup.js'],
testEnvironmentOptions: {
enzymeAdapter: 'react16',
},
};
我有一个父组件和一个子组件。
父组件:
const ParentComponent = () => {
const click_button = (role) => {
document.getElementById(role).innerHTML = role;
}
return (
<div>
<ChildButton id= 'button_child' name='button_1' onClick={() => {
click_button('role_1')
}}/>
<div>
<p id="role_1"/>
<p id="role_2"/>
<p id="role_3"/>
</div>
</div>
)
}
export default ParentComponent;
子组件
import React from 'react';
const ChildButton = (props) => {
return (
<React.Fragment>
<button onClick={props.onClick}>{props.name}</button>
</React.Fragment>
)
}
export default ChildButton;
ParentComponent
的测试之一:
it('buttons should render correctly', () => {
const wrapper shallow(<ParentComponent/>);
const instance = wrapper.instance();
jest.spyOn(instance, 'click_button');
expect(instance.click_button).toHaveBeenCalledTimes(0);
wrapper.find('#button_child').simulate('click');
expect(instance.click_button).toHaveBeenCalledTimes(1);
});
我的应用程序使用 jest 和 enzyme 进行测试。示例中的点击功能需要在 ParentComponent 中进行测试。但是,当我尝试访问该按钮时,测试失败了,这是因为该按钮位于 childButton
组件中。
所以基本上问题是如何测试 ParentComponent
中的 click_button
函数?
上面的例子实例是空的,酶文档说会是这种情况。现在我看到个人绕过这个的唯一方法是 'watching' 控制台日志,这对我来说似乎有点 hacky?
我正在努力坚持使用 Enzyme 和 Jest,因为这是我编写单元测试的内容,我希望我的集成测试可以效仿。
感谢您的帮助。
测试组件的行为而不是实现细节。使用 enzyme
的 mount()
函数一起测试父子组件。 React 功能组件没有实例,但 class 个组件有实例。
例如
parent.jsx
:
import ChildButton from './child';
const ParentComponent = () => {
const click_button = (role) => {
document.getElementById(role).innerHTML = role;
};
return (
<div>
<ChildButton
id="button_child"
name="button_1"
onClick={() => {
click_button('role_1');
}}
/>
<div>
<p id="role_1" />
<p id="role_2" />
<p id="role_3" />
</div>
</div>
);
};
export default ParentComponent;
child.jsx
:
import React from 'react';
const ChildButton = (props) => {
return (
<React.Fragment>
<button onClick={props.onClick}>{props.name}</button>
</React.Fragment>
);
};
export default ChildButton;
parent.test.jsx
:
import React from 'react';
import ParentComponent from './parent';
import { mount } from 'enzyme';
describe('66698493', () => {
beforeAll(() => {
const div = document.createElement('div');
div.setAttribute('id', 'container');
document.body.appendChild(div);
});
it('should change the inner HTML', () => {
const wrapper = mount(<ParentComponent />, { attachTo: document.getElementById('container') });
expect(document.getElementById('role_1').innerHTML).toEqual('');
wrapper.find('button').simulate('click');
expect(document.getElementById('role_1').innerHTML).toEqual('role_1');
});
});
测试结果:
PASS examples/66698493/parent.test.jsx
66698493
✓ should change the inner HTML (46 ms)
------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
------------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
child.jsx | 100 | 100 | 100 | 100 |
parent.jsx | 100 | 100 | 100 | 100 |
------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 6.067 s
jest.config.js
:
module.exports = {
preset: 'ts-jest/presets/js-with-ts',
testEnvironment: 'enzyme',
setupFilesAfterEnv: [
'jest-enzyme',
],
setupFiles: ['./jest.setup.js'],
testEnvironmentOptions: {
enzymeAdapter: 'react16',
},
};