React Test TypeError: Cannot read property 'map' of undefined

I'm trying to write a test to a component that uses the redux state as props and I'm getting the following error.

Should render expense list with expenses

  TypeError: Cannot read property 'map' of undefined

  at ExpenseList (src/components/Expenses_list.js:10:22)
  at node_modules/react-test-renderer/lib/shallow/ReactCompositeComponent.js:305:16
  at measureLifeCyclePerf (node_modules/react-test- 
  renderer/lib/shallow/ReactCompositeComponent.js:75:12)
  at ShallowComponentWrapper._constructComponentWithoutOwner (node_modules/react-test- 
  renderer/lib/shallow/ReactCompositeComponent.js:304:14)
  at ShallowComponentWrapper.mountComponent (node_modules/react-test- 
  renderer/lib/shallow/ReactCompositeComponent.js:187:21)
  at Object.mountComponent (node_modules/react-test-renderer/lib/shallow/ReactReconciler.js:45:35)
  at ReactShallowRenderer._render (node_modules/react-test- 
  renderer/lib/shallow/ReactShallowRenderer.js:138:23)
  at _batchedRender (node_modules/react-test-renderer/lib/shallow/ReactShallowRenderer.js:85:12)
  at Object.batchedUpdates (node_modules/react-test- 
  renderer/lib/shallow/ReactDefaultBatchingStrategy.js:60:14)
  at Object.batchedUpdates (node_modules/react-test-renderer/lib/shallow/ReactUpdates.js:97:27)
  at ReactShallowRenderer.render (node_modules/react-test- 
  renderer/lib/shallow/ReactShallowRenderer.js:112:18)
  at ReactShallowRenderer.render (node_modules/enzyme/build/react-compat.js:171:37)
  at node_modules/enzyme/build/ShallowWrapper.js:128:26
  at ReactDefaultBatchingStrategyTransaction.perform (node_modules/react-test- 
  renderer/lib/shallow/Transaction.js:143:20)
  at Object.batchedUpdates (node_modules/react-test- 
  renderer/lib/shallow/ReactDefaultBatchingStrategy.js:62:26)
  at Object.batchedUpdates (node_modules/react-test-renderer/lib/shallow/ReactUpdates.js:97:27)
  at ReactShallowRenderer.unstable_batchedUpdates (node_modules/react-test- 
  renderer/lib/shallow/ReactShallowRenderer.js:130:25)
  at performBatchedUpdates (node_modules/enzyme/build/ShallowWrapper.js:103:21)
  at node_modules/enzyme/build/ShallowWrapper.js:127:9
  at withSetStateAllowed (node_modules/enzyme/build/Utils.js:284:3)
  at new ShallowWrapper (node_modules/enzyme/build/ShallowWrapper.js:126:38)
  at shallow (node_modules/enzyme/build/shallow.js:19:10)
  at Object.<anonymous> (src/tests/components/ExpenseList.test.js:7:37)
      at new Promise (<anonymous>)
  at node_modules/p-map/index.js:46:16
  at processTicksAndRejections (internal/process/task_queues.js:94:5)

  PASS  src\tests\actions\expenses.test.js
  PASS  src\tests\reducers\filters.test.js
  PASS  src\tests\reducers\expenses.test.js
  PASS  src\tests\components\Header.test.js
  PASS  src\tests\selectors\expenses.test.js
  PASS  src\tests\actions\filters.test.js

  Test Suites: 1 failed, 6 passed, 7 total
  Tests:       1 failed, 28 passed, 29 total
  Snapshots:   1 passed, 1 total
  Time:        2.032s
  Ran all test suites.

  Watch Usage: Press w to show more.

       

The ExpenseList.js file

  import React from 'react';
  import { connect } from 'react-redux';
  import getFilteredExpenses from '../selectors/expenses_selector';
  import ExpenseListItem from './ExpenseListItem';

  export const ExpenseList = (props) => (
    <div>
      <h1>Expense List</h1>

      {props.expenses.map((expense) => (
        <ExpenseListItem key={expense.id} {...expense} />
      ))}
    </div>
  );

  const MapStateToProps = (state) => {
    return {
      expenses: getFilteredExpenses(state.expenses, state.filters),
    };
  };

  export default connect(MapStateToProps)(ExpenseList);

The ExpenseList.test.js file

          import React from 'react';
          import { shallow } from 'enzyme';
          import { ExpenseList } from '../../components/Expenses_list';
          import { expenses } from '../fixtures/expenses';
    
          test('Should render expense list with expenses', () => {
            const wrapper = shallow(<ExpenseList expenses={expenses} />);
            expect(wrapper).toMatchSnapshot();
          });
    
    

Package.json file

    {
      "name": "expensify-app",
      "version": "1.0.0",
      "main": "index.js",
      "author": "Henry Salim",
      "license": "MIT",
      "scripts": {
        "serve": "live-server public/",
        "build": "webpack",
        "dev-server": "webpack-dev-server",
        "test": "jest --config=jest.config.json"
      },
      "dependencies": {
        "babel-cli": "6.24.1",
        "babel-core": "6.25.0",
        "babel-jest": "^20.0.3",
        "babel-loader": "7.1.1",
        "babel-plugin-transform-class-properties": "6.24.1",
        "babel-plugin-transform-object-rest-spread": "^6.26.0",
        "babel-preset-env": "1.5.2",
        "babel-preset-react": "6.24.1",
        "css-loader": "0.28.4",
        "enzyme": "2.9.1",
        "enzyme-to-json": "1.5.1",
        "jest": "20.0.4",
        "live-server": "^1.2.0",
        "moment": "^2.29.1",
        "normalize.css": "^8.0.1",
        "path-to-regexp": "1.7.0",
        "react": "15.6.1",
        "react-addons-shallow-compare": "^15.6.2",
        "react-dates": "^21.8.0",
        "react-dom": "15.6.1",
        "react-modal": "2.2.2",
        "react-redux": "5.0.5",
        "react-router-dom": "^5.2.0",
        "react-test-renderer": "15.6.1",
        "redux": "^4.0.5",
        "sass-loader": "6.0.6",
        "style-loader": "0.18.2",
        "uuid": "^8.3.1",
        "validator": "8.0.0",
        "webpack": "3.1.0",
    "webpack-dev-server": "2.5.1"
    
      }
    }

The test expenses.js file

    import moment from 'moment';
    
    const expenses = [
      {
        id: '1',
        description: 'Gum',
        note: '',
        amount: 195,
        createdAt: 0,
      },
      {
        id: '2',
        description: 'Rent',
        note: '',
        amount: 109500,
        createdAt: moment(0).subtract(4, 'days').valueOf(),
      },
      {
        id: '3',
        description: 'Credit Card',
        note: '',
        amount: 4500,
        createdAt: moment(0).add(4, 'days').valueOf(),
      },
    ];
    
    export default expenses;

1 answer

  • answered 2020-11-06 19:22 Alexander Staroselsky

    Change the import of expenses to:

    import expenses from '../fixtures/expenses';
    

    It is a default export. Importing as a named export { expenses } expects an export of export const expenses or export default { expenses } or similar.