Создатели асинхронных действий Jest: TypeError: невозможно прочитать свойство then of undefined

Новичок, чтобы пошутить здесь. Я пытаюсь написать модульные тесты для одного из создателей асинхронных действий в моем проекте React, используя jest. Я продолжаю сталкиваться с ошибкой TypeError: Cannot read property 'then' of undefined

Ниже мой создатель действий:

import {loginService} from "./services";

export function login(email: string, password: string): (dispatch: ThunkDispatch<{}, {}, any>) => void {
  return dispatch => {
    dispatch(loggingIn(true));
    loginService(email, password).then(
      (response: any) => {
        dispatch(loggingIn(false));
        dispatch(loginAction(response));
      },
      error => {
       //Code
        }
        dispatch(loggingIn(false));
        dispatch(loginError(true, message));
      }
    );
  };
}

./services.js

export const loginService = (username: string, password: string) => {
  const requestOptions = {
    method: "POST",
    headers: {
      //Headers
    },
    body: JSON.stringify({email: username, password: password})
  };
  return fetch(`url`, requestOptions)
    .then(handleResponse, handleError)
    .then((user: any) => {
      //code
      return user;
    });
};

Ниже приведен мой тест:

it("login", () => {
    fetchMock
      .postOnce("/users/auth", {
        body: JSON.parse('{"email": "user", "password": "password"}'),
        headers: {"content-type": "application/json"}
      })
      .catch(() => {});
    const loginPayload = {email: "user", password: "password"};
    const expectedSuccessActions = [
      {type: types.LOGGING_IN, payload: true},
      {type: types.LOGIN, loginPayload}
    ];
    const expectedFailureActions = [
      {type: types.LOGGING_IN, payload: true},
      {type: types.LOGIN_ERROR, payload: {val: true, errorMessage: "error"}}
    ];
    const store = mockStore({user: {}});
    const loginService = jest.fn();
    return store.dispatch(LoginActions.login("email", "password")).then(() => {
      expect(store.getActions()).toEqual(expectedSuccessActions);
    });
  });

Пожалуйста помоги

1 ответ

Конечный результат, возвращенный отправкой вашего LoginActions.login() действие void (или undefined). НеPromise, поэтому не то, что вы можете назвать .then() в вашем тесте.

Судя по вашему тестовому коду, вы используете fetch-mock для тебя fetchMock. Вы должны дождаться его завершения, прежде чем проверять, отправил ли магазин правильные действия:

it("login", async () => {
//          ^^^^^ --> note that you need to make your test async to use await

    store.dispatch(LoginActions.login("email", "password"));
    await fetchMock.flush();

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

Обратите внимание, что комментарии в вашем коде, похоже, указывают на то, что ваш loginService делает еще кое-что, прежде чем вернуться из .then()перезвонить. Если это займет слишком много времени, дождитесьfetchMockчтобы закончить, возможно, не нужно ждать достаточно долго. В этом случае вам следует рассмотреть возможность возвратаPromise от твоего LoginActions.login()действие, чтобы вы могли его протестировать. Независимо от того или нет, вы должны зависит от того, сколько усилий было бы настроить приложение для обработки, что, так как вы не хотите, чтобы ваше приложение к сбою с любой необработанными ошибками отбраковки обещания в случае Логин терпит неудачу.

Другие вопросы по тегам