I am getting error the props. The error is from 'this.props.data.title' props. Following is my React component
* Parent Component *
<Location key={location.location_id} data={location} />
Component
import React, { Component } from 'react'
class Location extends Component {
render() {
const data = this.props.data
return (
<div className="location">
<p><strong>{data.title}</strong></p>
<div className="address">
<p className="small"> {data.address}</p>
</div>
</div>
)
}
}
export default Location
Test
import React from 'react'
import { expect } from 'chai'
import { shallow, mount, render } from 'enzyme'
import Location from '../src/scripts/components/location'
describe("<Location />", function() {
it("contains spec with an expectation", function() {
expect(shallow(<Location />).is('.location')).to.equal(true);
});
it('should have props for title and address', function () {
expect(shallow(<Location/>).props().data.title).to.be.defined;
expect(shallow(<Location/>).props().data.address).to.be.defined;
});
});
What am I missing here?
Error Details
<Location />
1) contains spec with an expectation
2) should have props for email and src
0 passing (45ms)
2 failing
1) <Location /> contains spec with an expectation:
TypeError: Cannot read property 'title' of undefined
at Location.render (src/scripts/components/location.js:8:33)
at [object Object].ReactCompositeComponentMixin._renderValidatedComponentWithoutOwnerOrContext (node_modules/react/lib/ReactCompositeComponent.js:808:34)
at [object Object].ReactCompositeComponentMixin.performInitialMount (node_modules/react/lib/ReactCompositeComponent.js:372:30)
at [object Object].ReactCompositeComponentMixin.mountComponent (node_modules/react/lib/ReactCompositeComponent.js:260:21)
at Object.ReactReconciler.mountComponent (node_modules/react/lib/ReactReconciler.js:47:35)
at [object Object].ReactShallowRenderer._render (node_modules/react/lib/ReactTestUtils.js:402:21)
at _batchedRender (node_modules/react/lib/ReactTestUtils.js:383:12)
at Object.ReactDefaultBatchingStrategy.batchedUpdates (node_modules/react/lib/ReactDefaultBatchingStrategy.js:61:7)
at Object.batchedUpdates (node_modules/react/lib/ReactUpdates.js:98:20)
at [object Object].ReactShallowRenderer.render (node_modules/react/lib/ReactTestUtils.js:376:16)
at [object Object].render (node_modules/enzyme/build/react-compat.js:153:39)
at node_modules/enzyme/build/ShallowWrapper.js:90:26
at ReactDefaultBatchingStrategyTransaction.Mixin.perform (node_modules/react/lib/Transaction.js:138:20)
at Object.ReactDefaultBatchingStrategy.batchedUpdates (node_modules/react/lib/ReactDefaultBatchingStrategy.js:63:19)
at batchedUpdates (node_modules/react/lib/ReactUpdates.js:98:20)
at node_modules/enzyme/build/ShallowWrapper.js:89:41
at withSetStateAllowed (node_modules/enzyme/build/Utils.js:196:3)
at new ShallowWrapper (node_modules/enzyme/build/ShallowWrapper.js:88:38)
at shallow (node_modules/enzyme/build/shallow.js:19:10)
at Context.<anonymous> (test/location-test.js:9:20)
2) <Location /> should have props for email and src:
TypeError: Cannot read property 'title' of undefined
at Location.render (src/scripts/components/location.js:8:33)
at [object Object].ReactCompositeComponentMixin._renderValidatedComponentWithoutOwnerOrContext (node_modules/react/lib/ReactCompositeComponent.js:808:34)
at [object Object].ReactCompositeComponentMixin.performInitialMount (node_modules/react/lib/ReactCompositeComponent.js:372:30)
at [object Object].ReactCompositeComponentMixin.mountComponent (node_modules/react/lib/ReactCompositeComponent.js:260:21)
at Object.ReactReconciler.mountComponent (node_modules/react/lib/ReactReconciler.js:47:35)
at [object Object].ReactShallowRenderer._render (node_modules/react/lib/ReactTestUtils.js:402:21)
at _batchedRender (node_modules/react/lib/ReactTestUtils.js:383:12)
at Object.ReactDefaultBatchingStrategy.batchedUpdates (node_modules/react/lib/ReactDefaultBatchingStrategy.js:61:7)
at Object.batchedUpdates (node_modules/react/lib/ReactUpdates.js:98:20)
at [object Object].ReactShallowRenderer.render (node_modules/react/lib/ReactTestUtils.js:376:16)
at [object Object].render (node_modules/enzyme/build/react-compat.js:153:39)
at node_modules/enzyme/build/ShallowWrapper.js:90:26
at ReactDefaultBatchingStrategyTransaction.Mixin.perform (node_modules/react/lib/Transaction.js:138:20)
at Object.ReactDefaultBatchingStrategy.batchedUpdates (node_modules/react/lib/ReactDefaultBatchingStrategy.js:63:19)
at batchedUpdates (node_modules/react/lib/ReactUpdates.js:98:20)
at node_modules/enzyme/build/ShallowWrapper.js:89:41
at withSetStateAllowed (node_modules/enzyme/build/Utils.js:196:3)
at new ShallowWrapper (node_modules/enzyme/build/ShallowWrapper.js:88:38)
at shallow (node_modules/enzyme/build/shallow.js:19:10)
at Context.<anonymous> (test/location-test.js:13:20)
It doesn't look like you're passing in any data
prop so this.data
is undefined
. You need to pass that to the component:
shallow(<Location data={someData} />)
Do you mean passing the location data on the test unit or the app? The app has the data, it's passed via the provider.
app.js
import React from 'react'
import ReactDOM from 'react-dom'
import { Provider } from 'react-redux'
import { createStore, applyMiddleware } from 'redux'
import thunk from 'redux-thunk' // A middleware that helps with async actions
import App from './components/app'
import reducers from './reducers'
const createStoreWithMiddleware = applyMiddleware(thunk)(createStore)
export const store = createStoreWithMiddleware(reducers, reducersData)
// Attaching AppInventory to window object
window.AppInventory = (opts) => {
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>
, document.querySelector('#'+ opts.elId))
}
location.js
if(data) {
return (
<div className="locations">
{_.map(data, location => {
return <Location key={location.location_id} data={location} />
})}
</div>
)
}
You're calling shallow
on Location
directly, meaning Location
is the only component being rendered here. That means that doing shallow(<Location />)
_only_ renders just that component, not your entire app. It's not being rendered within <App/>
or anything like that.
You need to manually pass in the props that your component expects, since they're not being provided by a parent component like in your actual application.
shallow(<Location data={mockData} />);
Most helpful comment
You're calling
shallow
onLocation
directly, meaningLocation
is the only component being rendered here. That means that doingshallow(<Location />)
_only_ renders just that component, not your entire app. It's not being rendered within<App/>
or anything like that.You need to manually pass in the props that your component expects, since they're not being provided by a parent component like in your actual application.