Enzyme: Error 'TypeError: Cannot read property 'title' of undefined'

Created on 23 Sep 2016  路  3Comments  路  Source: enzymejs/enzyme

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)

Most helpful comment

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} />);

All 3 comments

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} />);
Was this page helpful?
0 / 5 - 0 ratings