我很开玩笑,所以我不知道如何继续开玩笑。我已经使用jest编写了测试用例,用于更改输入和按钮单击以下组件。但它失败了。 “方法”道具“问题”仅适用于在单个节点上运行。 0找到了。“请帮帮我
代码:
import React from 'react';
import { Col } from 'react-bootstrap';
class FITB extends React.Component {
constructor(props) {
super(props);
this.String = String;
this.defaultTextSize = 8;
this.state = {
inputList: [],
splitList: [],
count: 0,
isValid: false
};
this.onInputChange = this.onInputChange.bind(this);
this.onClickSend = this.onClickSend.bind(this);
this.checkInputValidations = this.checkInputValidations.bind(this);
}
componentDidMount() {
this.initialize();
}
onInputChange(index) {
return (event) => {
const inputList = this.state.inputList;
let isValid = true;
inputList[index] = event.target.value;
if (!this.isValidInput(inputList[index])) {
isValid = false;
}
this.setState({
inputList,
isValid
});
// console.log('onInputChange fib state', this.state);
};
}
onClickSend() {
const {
splitList,
inputList,
count
} = this.state;
// console.log('onClickSend fib before state', this.state);
const onReply = this.props.onReply;
let fullText = '';
splitList.map((text, index) => {
fullText += text;
if ((index < count - 1) && inputList[index]) {
fullText += inputList[index];
}
return true;
});
if (onReply) {
onReply(fullText);
}
// console.log('onClickSend fib after state', this.state);
}
isValidInput(text) {
const regex = /^[\u0020-\u007e]*$/;
const replaceChar160RegExp = new RegExp(this.String.fromCharCode(160), 'g');
return regex.test(text.replace(replaceChar160RegExp, ' '));
}
initialize() {
let text = '';
this.props.messages.map((element) => {
if (element.type && (typeof element.type === 'string') && (element.type === 'FILL_IN_THE_BLANK')) {
text = element.message;
}
// console.log('inside fib', text);
return text;
});
const splitList = text.split(/_+/g);
this.setState({
splitList,
count: splitList.length
});
// console.log('init fib state', this.state);
}
checkInputValidations() {
const {
inputList,
count,
isValid
} = this.state;
let i;
let flag = false;
for (i = 0; i < count - 1; i += 1) {
if (!inputList[i] || inputList[i].trim() === '') {
flag = true;
}
}
// console.log('checkInputValidations', this.state);
return flag || !isValid;
}
render() {
const {
splitList,
count,
inputList
} = this.state;
// console.log('reder fitb', this.state);
return (
<Col lg={12} className="rply-block">
<Col lg={11} className="textarea-block">
<div className="fitb-wrap">
{ splitList && splitList.map((item, index) => (
<span>
<span className="fitb-text">{item}</span>
{ (index < count - 1) && (
<input
className="fitb-input"
type="text"
maxLength="40"
size={(inputList[index] && inputList[index].length > this.defaultTextSize && inputList[index].length) || this.defaultTextSize}
value={inputList[index]}
onChange={this.onInputChange(index)}
autoFocus={index === 0}
aria-describedby={count > 1 ? `Missing word ${index + 1} of ${count - 1}` : 'Missing word'}
aria-label="Fill in missing words"
/>
)}
</span>
))}
</div>
</Col>
<Col lg={1} className="">
<button
className="btn-info-dm"
role="button"
tabIndex="0"
onClick={this.onClickSend}
disabled={this.checkInputValidations()}
>Send</button>
</Col>
</Col>
);
}
}
FITB.propTypes = {
onReply: React.PropTypes.isRequired,
messages: React.PropTypes.array
};
export default FITB;
测试输入和按钮的文件
import React from 'react';
import FITB from '../components/dialogManager/fitb';
import { shallow } from 'enzyme';
import renderer from 'react-test-renderer';
describe('FITB', () => {
let component;
const mockFn = jest.fn();
beforeEach(() => {
component = shallow(<FITB onReply={mockFn} />);
});
test('Should initialize the FITB content', () => {
expect(component.find('.rply-block')).toHaveLength(1);
});
test('Should have been called send', () => {
component.find('.btn-info-dm').simulate('click');
expect(mockFn).toHaveBeenCalled();
});
test('Should render the text box', () => {
expect(component.state().inputList).toEqual([]);
expect(component.state().isValid).toEqual(false);
// expect(component.find('input.fitb-input')).toBeDefined();
console.log('state== ', component.state());
console.log('input == ', component.find('.fitb-input'));
component.find('.fitb-input').simulate('change', { target: { value: 'Qualitative data includes detailed interviews, direct _____, and historical records.' } });
console.log('fitb-input onchange== ', component.find('.fitb-input'));
expect(component.state().inputList).toEqual('Qualitative data includes detailed interviews, direct _____, and historical records.');
expect(component.state().isValid).toEqual(true);
});
// test('Should check the input label', () => {
// const expectedFitbTextLabel = 'Fill in missing words';
// const fitbTextList = [];
// console.log('span fitb txt== ', component.find('.fitb-text').instance().label);
// component.find('.fitb-text').map((elem) => {
// fitbTextList.push(elem.text().trim());
// });
// expect(component.find('.fitb-text').instance().label).toEqual(expectedFitbTextLabel);
// });
test('Should render the fitbText ', () => {
const expectedFitbText = 'Qualitative data includes detailed interviews, direct _____, and historical records.';
const fitbTextList = [];
console.log('span fitb txt== ', component.find('.fitb-text').text());
// fitbTextList.push(expectedFitbText.split(/_+/g));
// console.log('fitbTextList= ', fitbTextList);
component.find('.fitb-text').map((elem) => {
fitbTextList.push(elem.text().trim());
});
expect(fitbTextList).toEqual(expectedFitbText);
});
test('Should check the fitbText ', () => {
const expectedFitbText = 'Qualitative data includes detailed interviews, direct _____, and historical records.';
const fitbTextList = [];
fitbTextList.push(expectedFitbText.split(/_+/g));
expect(component.state().inputList).toEqual([]);
console.log('input list init== ', component.state().inputList);
component.find('input.fitb-input').simulate('change', { target: { value: 'test' } });
console.log('input list== ', component.state().inputList);
// component.find('input').instance().onInputChange(0);
// expect(component.state().inputList).toEqual('test');
});
});
按钮上的另一个组件单击以发送详细信息
import React from 'react';
class ReplyButtons extends React.Component {
constructor(props) {
super(props);
this.replyBtnWrap = '';
this.replyBtnList = '';
this.state = {
list: [],
isLeftArrowEnabled: false,
isRightArrowEnabled: false
};
this.onClickLeftArrow = this.onClickLeftArrow.bind(this);
this.onClickRightArrow = this.onClickRightArrow.bind(this);
this.onClickReplyBtn = this.onClickReplyBtn.bind(this);
}
componentDidMount() {
this.initializeList();
}
componentDidUpdate() {
this.checkElementOffset();
}
onClickRightArrow() {
const wrapElement = this.replyBtnWrap;
const listElement = this.replyBtnList;
const wrapWidth = wrapElement.offsetWidth;
const listWidth = listElement.offsetWidth;
let listLeft = wrapElement.scrollLeft;
let listOverflowWidth = 0;
listLeft += 400;
listOverflowWidth = listWidth - listLeft;
if (listOverflowWidth < 0) {
listLeft = listWidth - wrapWidth;
}
wrapElement.scrollLeft = listLeft;
this.checkElementOffset();
}
onClickLeftArrow() {
const wrapElement = this.replyBtnWrap;
let listLeft = wrapElement.scrollLeft;
listLeft -= 400;
if (listLeft < 0) {
listLeft = 0;
}
wrapElement.scrollLeft = listLeft;
this.checkElementOffset();
}
onClickReplyBtn(item) {
return () => {
const onReply = this.props.onReply;
if (onReply) {
onReply(item);
}
};
}
checkElementOffset() {
const wrapElement = this.replyBtnWrap;
const listElement = this.replyBtnList;
const wrapWidth = wrapElement.offsetWidth;
const listWidth = listElement.offsetWidth;
const listLeft = wrapElement.scrollLeft;
let listOverflowWidth = 0;
let isLeftArrowEnabled = false;
let isRightArrowEnabled = false;
if (listLeft > 0) {
isLeftArrowEnabled = true;
}
listOverflowWidth = listWidth - listLeft - wrapWidth;
if (listOverflowWidth > 0) {
isRightArrowEnabled = true;
}
if (this.state.isLeftArrowEnabled !== isLeftArrowEnabled || this.state.isRightArrowEnabled !== isRightArrowEnabled) {
this.setState({
isLeftArrowEnabled,
isRightArrowEnabled
});
}
}
initializeList() {
// this.setState({
// list: [{
// type: 'MENU_ITEM',
// text: 'what is quantitative research?',
// return_value: 'what is quantitative research?'
// }, {
// type: 'MENU_ITEM',
// text: 'what is mixed method research?',
// return_value: 'what is mixed method research?'
// }, {
// type: 'MENU_ITEM',
// text: 'what is qualitative research?',
// return_value: 'what is qualitative research?'
// }, {
// type: 'MENU_ITEM',
// text: 'I had a different question',
// return_value: 'I had a different question'
// }, {
// type: 'MENU_ITEM',
// text: 'That was actually my answer',
// return_value: 'That was actually my answer'
// }]
// });
const replyButtonText = [];
// console.log('reply btns props = ', this.props);
if (this.props.messages) {
this.props.messages.map((element) => {
if (element.type && (typeof element.type === 'string') && (element.type === 'MENU_ITEM')) {
replyButtonText.push(element);
}
return this.setState({ list: replyButtonText });
});
}
}
render() {
const btnList = this.state.list;
const {
isLeftArrowEnabled,
isRightArrowEnabled
} = this.state;
return (
<div className="r-wrap">
{ isLeftArrowEnabled && (
<button className="r-btn-left-arrow" onClick={this.onClickLeftArrow} role="button" tabIndex="0">
<i className="glyphicon glyphicon-menu-left" />
</button>
)}
<div className="r-btn-wrap" ref={(e) => { this.replyBtnWrap = e; }}>
<div className="r-btn-list" ref={(e) => { this.replyBtnList = e; }}>
{
btnList && btnList.map(btnItem => <button
className="r-btn"
role="button"
tabIndex="0"
onClick={this.onClickReplyBtn(btnItem)}
title={btnItem.text}
>{btnItem.text}</button>)
}
</div>
</div>
{ isRightArrowEnabled && (
<button className="r-btn-right-arrow" onClick={this.onClickRightArrow} role="button" tabIndex="0">
<i className="glyphicon glyphicon-menu-right" />
</button>
)}
</div>
);
}
}
ReplyButtons.propTypes = {
onReply: React.PropTypes.isRequired,
messages: React.PropTypes.array
};
export default ReplyButtons;
测试文件:
import React from 'react';
import ReplyButtons from '../components/dialogManager/replybuttons';
import { shallow } from 'enzyme';
import renderer from 'react-test-renderer';
const mockOutputObj = [{
type: 'MENU_ITEM',
text: 'what is quantitative research?',
return_value: 'what is quantitative research?'
}, {
type: 'MENU_ITEM',
text: 'what is mixed method research?',
return_value: 'what is mixed method research?'
}];
describe('ReplyButtons', () => {
let component;
const mockFn = jest.fn();
beforeEach(() => {
component = shallow(<ReplyButtons onReply={mockFn} />);
});
test('Should initialize the ReplyButtons content', () => {
expect(component.find('.r-wrap')).toHaveLength(1);
});
test('Should check the ReplyButtons click', () => {
console.log('r-btn==> ', component.find('button.r-btn'));
component.find('.r-btn').simulate('click');
expect(mockFn).toHaveBeenCalled();
});
});
请帮帮我。
答案 0 :(得分:0)
我认为错误发生的原因是上一个测试用例中的选择器
public class SplitPaneDemo extends JFrame implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new SplitPaneDemo());
}
ExtOneTouchJSplitPane hSplitPane;
ExtOneTouchJSplitPane vSplitPane;
public SplitPaneDemo() {
createView();
}
public void createView() {
setTitle("SplitPane-Demo");
setLayout(new BorderLayout(0, 0));
hSplitPane = new ExtOneTouchJSplitPane();
JButton jBLeft = new JButton("<html><body> <br>Left Component<br> </body></html>");
JButton jBRight = new JButton("<html><body> <br>Right Component<br> </body></html>");
jBLeft.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
hSplitPane.oneTouchClickLeft();
}
});
jBRight.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
hSplitPane.oneTouchClickRight();
}
});
hSplitPane.setLeftComponent(jBLeft);
hSplitPane.setRightComponent(jBRight);
add(hSplitPane, BorderLayout.CENTER);
vSplitPane = new ExtOneTouchJSplitPane(JSplitPane.VERTICAL_SPLIT);
JButton jBUp = new JButton("<html><body> <br>Up Component<br> </body></html>");
JButton jBDown = new JButton("<html><body> <br>Down Component<br> </body></html>");
jBUp.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
vSplitPane.oneTouchClickUp();
}
});
jBDown.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
vSplitPane.oneTouchClickDown();
}
});
vSplitPane.setTopComponent(jBUp);
vSplitPane.setBottomComponent(jBDown);
add(vSplitPane, BorderLayout.SOUTH);
}
@Override
public void run() {
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(400, 400);
setVisible(true);
hSplitPane.oneTouchClickLeft();
}
}
指的是通过迭代ReplyButtons组件中的this.state.list构建的按钮
并且您没有提供会触发向列表提供信息的道具'消息'
尝试使用一些消息(例如
)实现ReplyButtonscomponent.find('button.r-btn')
它应该没问题(顺便说一下,这里没有错误堆栈是不可能的,可能还有其他问题)