酶/反应单元测试
Enzyme / React Unit test
我只有这个 React 函数 UI 组件,它传入了两个 props,第二个是从其父组件传递的函数。 onClick 调用 'delegates' 到父容器组件中的一个函数,然后该父方法负责调度到 redux store。
import React, {Component} from 'react';
import PropTypes from 'prop-types';
const BotShowUI = ({ bot, onClick }) => {
return(
<div id={bot.id} onClick={onClick}>
{bot.id} : {bot.text}
</div>
)
}
BotShowUI.propTypes = {
bot: PropTypes.object.isRequired,
onClick: PropTypes.func.isRequired
};
export default BotShowUI;
我的测试规范是,它使用 Jasmine
import React, {Component} from 'react';
import { mount } from 'enzyme';
import BotShowUI from '../botShowUI';
function onClickFunction(){};
describe('botShowUI', () => {
const bot = {id: 1, isDone: false, text: 'bot 123'};
const expectedDivText = '1 : bot 123';
const wrapper = mount(<BotShowUI bot={bot} onClick={onClickFunction} />);
it(' div has been rendered ', () => {
expect(wrapper.find('div').first()).not.toBe(null);
});
it(' div displays the correct bot text ', () => {
expect(wrapper.find('div').first().text()).toEqual(expectedDivText)
});
it(' div click event fired ', () => {
wrapper.simulate('click');
expect(wrapper.state('onClick')).toBe(true);
});
});
最后一个断言失败
Chrome 57.0.2987 (Windows 10 0.0.0) botShowUI div click event fired FAILED
TypeError: Cannot read property 'onClick' of null
at ReactWrapper.state (webpack:///~/enzyme/build/ReactWrapper.js:825:24 <- tests.webpack.js:26303:25)
at Object.<anonymous> (webpack:///app/react/components/bots/_tests/botShowUI.spec.js:25:23 <- tests.webpack.js:25415:25)
wrapper.simulate('click');
有效,但下一行失败
断言点击被触发的正确方法是什么?
我是否必须放入包装器的 props/children 而不是使用状态?
我不打算以任何方式测试父容器,两者是隔离的。
此测试仅与此 UI 组件有关。
首先是 onClick 不在 state 上,而是在 props 上,所以你必须通过 wrapper.props('onClick')
.
来访问它
其次,检测onClick是否被处理是使用spy,而不是空函数。如果你不想使用间谍,你仍然可以这样做,但不是你做的方式。如果您有兴趣,我也可以 post 一些伪代码。但是回到使用间谍,您可以使用间谍作为 onClick 道具。下面是代码。我是手写的,所以请检查是否有任何语法错误,但你应该知道需要做什么。
it('should call the onClick handler on click', () => {
const onClickFunction = sinon.spy()
wrapper = mount(<BotShowUI bot={bot} onClick={onClickFunction} />)
wrapper.simulate('click');
expect(onClickFunction).toHaveBeenCalled();
})
根据 Abhishek 的回答,这是我对 Jasmine 的解决方案
it(' div click event fired ', () => {
let onClickFunction_spy = jasmine.createSpy('onClickFunction');
const wrapper = mount(<BotShowUI bot={bot} onClick={onClickFunction_spy} />);
wrapper.simulate('click');
expect(onClickFunction_spy).toHaveBeenCalled();
});
希望这对任何人都有帮助。
我只有这个 React 函数 UI 组件,它传入了两个 props,第二个是从其父组件传递的函数。 onClick 调用 'delegates' 到父容器组件中的一个函数,然后该父方法负责调度到 redux store。
import React, {Component} from 'react';
import PropTypes from 'prop-types';
const BotShowUI = ({ bot, onClick }) => {
return(
<div id={bot.id} onClick={onClick}>
{bot.id} : {bot.text}
</div>
)
}
BotShowUI.propTypes = {
bot: PropTypes.object.isRequired,
onClick: PropTypes.func.isRequired
};
export default BotShowUI;
我的测试规范是,它使用 Jasmine
import React, {Component} from 'react';
import { mount } from 'enzyme';
import BotShowUI from '../botShowUI';
function onClickFunction(){};
describe('botShowUI', () => {
const bot = {id: 1, isDone: false, text: 'bot 123'};
const expectedDivText = '1 : bot 123';
const wrapper = mount(<BotShowUI bot={bot} onClick={onClickFunction} />);
it(' div has been rendered ', () => {
expect(wrapper.find('div').first()).not.toBe(null);
});
it(' div displays the correct bot text ', () => {
expect(wrapper.find('div').first().text()).toEqual(expectedDivText)
});
it(' div click event fired ', () => {
wrapper.simulate('click');
expect(wrapper.state('onClick')).toBe(true);
});
});
最后一个断言失败
Chrome 57.0.2987 (Windows 10 0.0.0) botShowUI div click event fired FAILED
TypeError: Cannot read property 'onClick' of null
at ReactWrapper.state (webpack:///~/enzyme/build/ReactWrapper.js:825:24 <- tests.webpack.js:26303:25)
at Object.<anonymous> (webpack:///app/react/components/bots/_tests/botShowUI.spec.js:25:23 <- tests.webpack.js:25415:25)
wrapper.simulate('click');
有效,但下一行失败
断言点击被触发的正确方法是什么?
我是否必须放入包装器的 props/children 而不是使用状态?
我不打算以任何方式测试父容器,两者是隔离的。 此测试仅与此 UI 组件有关。
首先是 onClick 不在 state 上,而是在 props 上,所以你必须通过 wrapper.props('onClick')
.
其次,检测onClick是否被处理是使用spy,而不是空函数。如果你不想使用间谍,你仍然可以这样做,但不是你做的方式。如果您有兴趣,我也可以 post 一些伪代码。但是回到使用间谍,您可以使用间谍作为 onClick 道具。下面是代码。我是手写的,所以请检查是否有任何语法错误,但你应该知道需要做什么。
it('should call the onClick handler on click', () => {
const onClickFunction = sinon.spy()
wrapper = mount(<BotShowUI bot={bot} onClick={onClickFunction} />)
wrapper.simulate('click');
expect(onClickFunction).toHaveBeenCalled();
})
根据 Abhishek 的回答,这是我对 Jasmine 的解决方案
it(' div click event fired ', () => {
let onClickFunction_spy = jasmine.createSpy('onClickFunction');
const wrapper = mount(<BotShowUI bot={bot} onClick={onClickFunction_spy} />);
wrapper.simulate('click');
expect(onClickFunction_spy).toHaveBeenCalled();
});
希望这对任何人都有帮助。