简体   繁体   中英

Getting .then of undefined when trying to test a dispatch action function in React/Redux/Jest

component › toggleNotification actions › creates NOTIFICATION_REMOVE after successfull NOTIFICATION_ADD (error)

TypeError: Cannot read property 'then' of undefined

In my changePassword component

3 dispatch functions, and focusing on testing the toggleNotification.

const mapDispatchToProps = dispatch => ({
  verifyEmail: (...args) => { dispatch(verifyEmail(...args)); },
  toggleNotification: (flag, msg, type) => { dispatch(toggleNotification(flag, msg, type)); },
  displayError: (error, errMsg) => { dispatch(displayError(error, errMsg)); }
});

The toggleNotification dispatch function in /actions

export const toggleNotification = (notification, message, type) => (dispatch) => {
  if (notification === true) {
    dispatch({
      type: NOTIFICATION_ADD,
      payload: {
        message,
        type
      }
    });
    setTimeout(() => {
      dispatch({
        type: NOTIFICATION_REMOVE
      });
    }, 7000);
  }
};

Finally my changePassword.test.js

import React from 'react';
import { shallow } from 'enzyme';
import toJson from 'enzyme-to-json';

// Testing packages
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import expect from 'expect';

// Actions
import { verifyEmail, toggleNotification } from 'actions';

// Action Types
import { NOTIFICATION_ADD, NOTIFICATION_REMOVE } from 'actionTypes';

// String Constants
import { CHANGE_PASS_NOT_MATCH } from 'copy/Components/login';

// Component to test
import { ChangePasswordJest } from './changePassword';

const middlewares = [thunk];
const mockStore = configureMockStore(middlewares);

describe('<ChangePassword /> component', () => {
  const wrapper = shallow(<ChangePasswordJest />);

  describe('when rendering', () => {
    it('should render', () => {
      const tree = toJson(wrapper);
      expect(tree).toMatchSnapshot();
      expect(wrapper).toHaveLength(1);
    });
  });

  describe('toggleNotification actions', () => {
    it('creates NOTIFICATION_REMOVE after successfull NOTIFICATION_ADD (error)', () => {
      const expectedActions = [
        {
          type: NOTIFICATION_ADD,
          payload: {
            notification: true,
            message: CHANGE_PASS_NOT_MATCH,
            type: 'error'
          }
        },
        { type: NOTIFICATION_REMOVE }
      ];

      const store = mockStore();

      console.log('store -->', store);
      console.log('toggleNotification -->', toggleNotification);

      return store.dispatch(toggleNotification(true, CHANGE_PASS_NOT_MATCH, 'error')).then(() => {
      // return of async actions
        expect(store.getActions()).toEqual(expectedActions);
      });
    });
  });
});

In the terminal my console logs print out store and toggleNotification as expected:

在此处输入图片说明

Any thoughts or ideas why I'm getting

TypeError: Cannot read property 'then' of undefined

On

return store.dispatch(toggleNotification(true, CHANGE_PASS_NOT_MATCH, 'error'))
  .then(() => {
     // return of async actions
     expect(store.getActions()).toEqual(expectedActions);
});

The problem was that my toggleNotifcations function wasn't actually a Promise.

export const toggleNotification = (notification, message, type) => (dispatch) => {
  if (notification === true) {
    dispatch({
      type: NOTIFICATION_ADD,
      payload: {
        message,
        type
      }
    });

    setTimeout(() => {
      dispatch({
        type: NOTIFICATION_REMOVE
      });
    }, 7000);
  }
};

Instead all I needed to do in my test was just call that dispatch function:

describe('toggleNotification actions', () => {
  let store;

  beforeEach(() => {
    store = mockStore();
  });

  it('dispatches a NOTIFICATION_ADD (passwords don\'t match error)', () => {
    const expectedActions = [
      {
        type: NOTIFICATION_ADD,
        payload: {
          message: CHANGE_PASS_NOT_MATCH,
          type: 'error'
        }
      }
    ];

    store.dispatch(toggleNotification(true, CHANGE_PASS_NOT_MATCH, 'error'));

    console.log('store.getActions()', store.getActions());

    expect(store.getActions()).toEqual(expectedActions);
  });
});

在此处输入图片说明

New problem now is that even though I have a passing test for that dispatch action. It did nothing for the coverage!

Will be posting a new question related to this new issue:

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM