我的笑话+酶mount()测试遇到问题。我正在测试一个功能,该功能可以切换显示组件。
mount()
组件之间的开关:当state.infoDisplayContent = 'mission'一个missionControl部件被安装时,当state.infoDisplayContent = 'profile'-其它组分的步骤中:
state.infoDisplayContent = 'mission'
missionControl
state.infoDisplayContent = 'profile'
_modifyAgentStatus () { const { currentAgentProfile, agentsDatabase } = this.state; const agentToMod = currentAgentProfile; if (agentToMod.status === 'Free') { this.setState({ infoDisplayContent: 'mission' }); agentToMod.status = 'Waiting'; } else if (agentToMod.status === 'Waiting') { const locationSelect = document.getElementById('missionLocationSelect'); agentToMod.location = locationSelect[locationSelect.selectedIndex].innerText; agentToMod.status = 'On Mission'; this.setState({ infoDisplayContent: 'profile' }); } }
当我触发此函数时,一切看起来都很好,该测试运行良好,并且测试成功通过了所需的组件:
import React from 'react'; import { mount } from 'enzyme'; import App from '../containers/App'; const result = mount( <App /> ) test('change mission controls', () => { expect(result.state().currentAgentProfile.status).toBe('Free'); result.find('#statusController').simulate('click'); expect(result.find('#missionControls')).toHaveLength(1); expect(result.find('#missionLocationSelect')).toHaveLength(1); expect(result.state().currentAgentProfile.status).toBe('Waiting'); }); But when I simulate onClick two times: test('change mission controls', () => { expect(result.state().currentAgentProfile.status).toBe('Free'); result.find('#statusController').simulate('click'); expect(result.find('#missionControls')).toHaveLength(1); expect(result.find('#missionLocationSelect')).toHaveLength(1); expect(result.state().currentAgentProfile.status).toBe('Waiting'); result.find('#statusController').simulate('click'); expect(result.state().currentAgentProfile.status).toBe('On Mission'); });
我得到这个断言:
TypeError: Cannot read property 'selectedIndex' of null at App._modifyAgentStatus (development/containers/App/index.js:251:68) at Object.invokeGuardedCallback [as invokeGuardedCallbackWithCatch] (node_modules/react-dom/lib/ReactErrorUtils.js:26:5) at executeDispatch (node_modules/react-dom/lib/EventPluginUtils.js:83:21) at Object.executeDispatchesInOrder (node_modules/react-dom/lib/EventPluginUtils.js:108:5) at executeDispatchesAndRelease (node_modules/react-dom/lib/EventPluginHub.js:43:22) at executeDispatchesAndReleaseSimulated (node_modules/react-dom/lib/EventPluginHub.js:51:10) at forEachAccumulated (node_modules/react-dom/lib/forEachAccumulated.js:26:8) at Object.processEventQueue (node_modules/react-dom/lib/EventPluginHub.js:255:7) at node_modules/react-dom/lib/ReactTestUtils.js:350:22 at ReactDefaultBatchingStrategyTransaction.perform (node_modules/react-dom/lib/Transaction.js:140:20) at Object.batchedUpdates (node_modules/react-dom/lib/ReactDefaultBatchingStrategy.js:62:26) at Object.batchedUpdates (node_modules/react-dom/lib/ReactUpdates.js:97:27) at node_modules/react-dom/lib/ReactTestUtils.js:348:18 at ReactWrapper.<anonymous> (node_modules/enzyme/build/ReactWrapper.js:776:11) at ReactWrapper.single (node_modules/enzyme/build/ReactWrapper.js:1421:25) at ReactWrapper.simulate (node_modules/enzyme/build/ReactWrapper.js:769:14) at Object.<anonymous> (development/tests/AgentProfile.test.js:26:38) at process._tickCallback (internal/process/next_tick.js:109:7)
显而易见的是:
document.getElementById('missionLocationSelect');
返回null,但我无法理解为什么。正如我提到的那样,元素通过了测试。
expect(result.find('#missionLocationSelect')).toHaveLength(1);
但无法使用捕获document.getElementById()。
document.getElementById()
请帮助我解决此问题并运行测试。
通过hung和Google之神找到了解决方案:
attachTo
const result = mount( <App />, { attachTo: document.body } );
agentToMod.location = locationSelect.options[locationSelect.selectedIndex].text;` : _modifyAgentStatus () { const { currentAgentProfile, agentsDatabase } = this.state; const agentToMod = currentAgentProfile; if (agentToMod.status === 'Free') { this.setState({ infoDisplayContent: 'mission' }); agentToMod.status = 'Waiting'; } else if (agentToMod.status === 'Waiting') { const locationSelect = document.getElementById('missionLocationSelect'); agentToMod.location = agentToMod.location = locationSelect.options[locationSelect.selectedIndex].text; agentToMod.status = 'On Mission'; this.setState({ infoDisplayContent: 'profile' }); } }