I am using Enzyme to test a d3 chart component. I encounter a problem that d3.select cannot find the container div as well as this error message:
TypeError: Cannot read property 'getAttribute' of null
Here's my code:
Chart component file: ProgramMeasureTrendsComponent.js
class ProgramMeasureTrendsComponent extends Component {
constructor(props){
super(props);
}
render() {
return (
<div className='programTrendChartContainer'></div>
**this is the d3 container div that d3 select cannot find.**
)
}
componentDidMount() {
this.createBarChart()
**use componentDidMount to render d3 chart.**
}
createBarChart() {
let { parsedData,xAxisKeys,chartTitle,width,height,
marginTop,marginLeft,marginBottom,marginRight } = this.props;
let keys = Object.keys(parsedData[0]).slice(0, 5);
let container = d3.select('.programTrendChartContainer');<=== getting error at this line
......
Test case file:
describe('<ProgramMeasureTrendsComponent />', () => {
it('Renders ProgramMeasureTrends Component', () => {
let store = mockStore({"dashboard":{"main":{"currentPeriod":"MONTH"}}});
const input = [
{
month:"Jan",
elevated:0,
group:"1486022400000",
hyperCrisis:0,
hyperStage1:0,
hyperStage2:0,
normal:0,
total:0
},
{
month:"Feb",
elevated:0,
group:"1488441600000",
hyperCrisis:0,
hyperStage1:0,
hyperStage2:0,
normal:0,
total:0
},
{
month:"Mar",
elevated:0,
group:"1491116400000",
hyperCrisis:0,
hyperStage1:0,
hyperStage2:0,
normal:0,
total:0
},
{
month:"Apr",
elevated:0,
group:"1493708400000",
hyperCrisis:0,
hyperStage1:0,
hyperStage2:0,
normal:0,
total:0
}
]
let container = mount( <ProgramMeasureTrendsComponent
store={store}
parsedData = { input }
xAxisKeys = {["Jan","Feb","Mar","Apr"]}
chartTitle = 'd3 chart title'
width = '400'
height = '400'
marginTop = '20'
marginBottom = '20'
marginLeft = '20'
marginRight = '20'
/>);
container.debug();
});
})
Error output
<ProgramMeasureTrendsComponent /> Renders ProgramMeasureTrends Component:
TypeError: Cannot read property 'getAttribute' of null
at Selection.selection_attr [as attr] (node_modules/d3-selection/build/d3-selection.js:590:16)
at ProgramMeasureTrendsComponent.createBarChart (src/modules/dashboard/main/components/ProgramMeasureTrendsComponent.js:47:30)
at ProgramMeasureTrendsComponent.componentDidMount (src/modules/dashboard/main/components/ProgramMeasureTrendsComponent.js:28:14)
at node_modules/react-dom/lib/ReactCompositeComponent.js:265:25
at measureLifeCyclePerf (node_modules/react-dom/lib/ReactCompositeComponent.js:75:12)
at node_modules/react-dom/lib/ReactCompositeComponent.js:264:11
at CallbackQueue.notifyAll (node_modules/react-dom/lib/CallbackQueue.js:76:22)
at ReactReconcileTransaction.close (node_modules/react-dom/lib/ReactReconcileTransaction.js:80:26)
at ReactReconcileTransaction.closeAll (node_modules/react-dom/lib/Transaction.js:206:25)
at ReactReconcileTransaction.perform (node_modules/react-dom/lib/Transaction.js:153:16)
at batchedMountComponentIntoNode (node_modules/react-dom/lib/ReactMount.js:126:15)
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 Object._renderNewRootComponent (node_modules/react-dom/lib/ReactMount.js:320:18)
at Object._renderSubtreeIntoContainer (node_modules/react-dom/lib/ReactMount.js:401:32)
at Object.render (node_modules/react-dom/lib/ReactMount.js:422:23)
at Object.renderIntoDocument (node_modules/react-dom/lib/ReactTestUtils.js:91:21)
at renderWithOptions (node_modules/enzyme/build/react-compat.js:200:24)
at new ReactWrapper (node_modules/enzyme/build/ReactWrapper.js:94:59)
at mount (node_modules/enzyme/build/mount.js:19:10)
at Context.<anonymous> (test/modules/dashboard/ProgramMeasureTrendsComponent.spec.js:53:25)
In my app, this chart rendered properly without any error, but when I test it the above error is shown.
My guess is that the container div is not rendered when componentDidMount() is called in Enzyme's testing process.
Is Enzyme's component lifecycle different than the React lifecycle?