如何测试子组件从父组件的 getChildContext() 获取正确的上下文?
How to test children components get proper context from parent's getChildContext()?
我有一个具有 getChildContext() 方法的组件和接收从父项的 props 派生的上下文的子项。
如何测试他们是否已收到?
这是组件的代码...一些选项卡组件。
The tab:
function _handleTabChange(eventKey, id, tabsChange, e) {
e.preventDefault();
tabsChange({ id, eventKey });
}
const _Tab = ({ eventKey, children, ...props }, { activeKey, parentContainer, tabsChange }) => (
<li className={classNames('b-tab', { active: eventKey === activeKey })} {...props}>
<a href="#"
role="tab"
data-toggle="tab"
onClick={_handleTabChange.bind(this, eventKey, parentContainer, tabsChange)}>
{children}
</a>
</li>
);
The Tab Container:
class _TabContainer extends Component {
static displayName = 'TabContainer'
static propTypes = {
children: PropTypes.node.isRequired,
tabsAddContainer: PropTypes.func.isRequired,
tabsRemoveContainer: PropTypes.func.isRequired,
tabsChange: PropTypes.func.isRequired,
tabs: PropTypes.object.isRequired,
tabContainerID: PropTypes.string,
}
static childContextTypes = {
parentContainer: PropTypes.string.isRequired,
tabsChange: PropTypes.func.isRequired,
activeKey: PropTypes.number.isRequired,
}
constructor(props) {
super(props);
this.clones = Children.map(this.props.children, (element, eventKey) => {
if (element.props.active) {
this.defaultActive = eventKey;
}
console.log("defaultActive", this.defaultActive);
return cloneElement(element, { eventKey });
});
}
getChildContext() {
const { tabContainerID, tabsChange, tabs } = this.props;
//activeKey is tabs[tabContainerID] unless it hasn't been instantiated, in which case
//it is the defaultActive gathered by mapping over Tabs to find one with an active prop
const activeKey = (tabs && tabs[tabContainerID] && tabs[tabContainerID] !== '') ?
tabs[tabContainerID] :
this.defaultActive;
return {
parentContainer: tabContainerID,
activeKey,
tabsChange,
};
}
componentWillMount() {
const { tabContainerID, tabsAddContainer } = this.props;
if (tabContainerID) {
tabsAddContainer({ tabContainerID, defaultActive: this.defaultActive });
}
}
componentWillUnmount() {
const { tabContainerID, tabsRemoveContainer } = this.props;
if (tabContainerID) {
tabsRemoveContainer(tabContainerID);
}
}
defaultActive = 0;
render() {
const { children, tabsChange, ...restProps } = this.props;
return (
<div {...restProps} className='tab-container'>
<ul className='nav nav-tabs nav-default' role='tablist'>
{this.clones}
</ul>
</div>
);
}
}
实际上,这不是必需的 - 您可以信任 getChildContext() 并仅测试 return 是否是预期数据。
为此,创建一个函数来return 必要的逻辑并测试该函数,它将在 getChildContext() 中调用。
我有一个具有 getChildContext() 方法的组件和接收从父项的 props 派生的上下文的子项。
如何测试他们是否已收到?
这是组件的代码...一些选项卡组件。
The tab:
function _handleTabChange(eventKey, id, tabsChange, e) {
e.preventDefault();
tabsChange({ id, eventKey });
}
const _Tab = ({ eventKey, children, ...props }, { activeKey, parentContainer, tabsChange }) => (
<li className={classNames('b-tab', { active: eventKey === activeKey })} {...props}>
<a href="#"
role="tab"
data-toggle="tab"
onClick={_handleTabChange.bind(this, eventKey, parentContainer, tabsChange)}>
{children}
</a>
</li>
);
The Tab Container:
class _TabContainer extends Component {
static displayName = 'TabContainer'
static propTypes = {
children: PropTypes.node.isRequired,
tabsAddContainer: PropTypes.func.isRequired,
tabsRemoveContainer: PropTypes.func.isRequired,
tabsChange: PropTypes.func.isRequired,
tabs: PropTypes.object.isRequired,
tabContainerID: PropTypes.string,
}
static childContextTypes = {
parentContainer: PropTypes.string.isRequired,
tabsChange: PropTypes.func.isRequired,
activeKey: PropTypes.number.isRequired,
}
constructor(props) {
super(props);
this.clones = Children.map(this.props.children, (element, eventKey) => {
if (element.props.active) {
this.defaultActive = eventKey;
}
console.log("defaultActive", this.defaultActive);
return cloneElement(element, { eventKey });
});
}
getChildContext() {
const { tabContainerID, tabsChange, tabs } = this.props;
//activeKey is tabs[tabContainerID] unless it hasn't been instantiated, in which case
//it is the defaultActive gathered by mapping over Tabs to find one with an active prop
const activeKey = (tabs && tabs[tabContainerID] && tabs[tabContainerID] !== '') ?
tabs[tabContainerID] :
this.defaultActive;
return {
parentContainer: tabContainerID,
activeKey,
tabsChange,
};
}
componentWillMount() {
const { tabContainerID, tabsAddContainer } = this.props;
if (tabContainerID) {
tabsAddContainer({ tabContainerID, defaultActive: this.defaultActive });
}
}
componentWillUnmount() {
const { tabContainerID, tabsRemoveContainer } = this.props;
if (tabContainerID) {
tabsRemoveContainer(tabContainerID);
}
}
defaultActive = 0;
render() {
const { children, tabsChange, ...restProps } = this.props;
return (
<div {...restProps} className='tab-container'>
<ul className='nav nav-tabs nav-default' role='tablist'>
{this.clones}
</ul>
</div>
);
}
}
实际上,这不是必需的 - 您可以信任 getChildContext() 并仅测试 return 是否是预期数据。
为此,创建一个函数来return 必要的逻辑并测试该函数,它将在 getChildContext() 中调用。