我正在尝试将上下文传递给React组件,但因为我正在使用Enzyme进行测试,所以我想动态地将组件添加到其父组件中,以便检查其状态。测试看起来像这样:
describe('<BeaconConfig />', () => {
it('inherits the config from BeaconConfig', () => {
mount(<BeaconConfig persistent><div id="parent"></div></BeaconConfig>, { attachTo: document.body });
const wrapper = mount(<Beacon/>, { attachTo: document.getElementById('parent') });
expect(wrapper.state('persistent')).to.be(true);
});
});
测试失败,因为persistent
组件状态的Beacon
属性为undefined
,但它应该通过上下文从BeaconConfig
继承。
当我在挂载Beacon
时尝试将BeaconConfig
直接放在JSX中时,它可以正常工作,但在这种情况下,Enzyme不会让我进入Beacon
组件状态它不是根源。
当我将动态添加到其父组件时,React没有将上下文传播到我的组件是否正常?
答案 0 :(得分:1)
React没有传播上下文是正常的 - 它不会查看DOM并以这种方式将其与VDOM区分开来。
您希望在初始安装中将其设为子项,并使用MountWrapper的.find()
或.children()
方法(docs)来挖掘孩子,找到灯塔并做你的断言。
答案 1 :(得分:0)
以下是我最终使用的完整测试:
describe('Context', () => {
let wrapper;
let parent;
const open = stub().returns({});
const mockIndexedDB = { open };
const config = mount(<BeaconConfig persistent position="bottom" indexedDB={mockIndexedDB} />);
beforeEach(() => {
parent = document.createElement('div');
document.body.appendChild(parent);
wrapper = mount(<Beacon>some text</Beacon>, {
attachTo: parent,
context: config.instance().getChildContext()
});
});
afterEach(() => {
wrapper.detach();
document.body.removeChild(document.body.firstChild);
});
it('overrides the default values with the context if any', () => {
expect(wrapper.state('persistent')).to.be(true);
expect(wrapper.state('position')).to.be('bottom');
expect(open.calledOnce).to.equal(true);
});
});
@STRML提出了一个很好的建议,但我认为不可能访问非根组件的状态。
相反,我会孤立地实例化BeaconConfig
并抓住它的子上下文,使用Beacon
options
参数手动将其传递给mount
。这测试BeaconConfig
创建正确的子上下文,Beacon
正确使用上下文。当后者是后代时,它不测试BeaconConfig
将配置传递给Beacon
,但我们可以认为这是理所当然的,因为它是基本的React功能。