Jest异步操作创建者:TypeError:无法读取未定义的属性'then'

问题描述 投票:0回答:1

这里是Kinda的新手。我正在尝试使用jest为我的React项目中的一个异步动作创建者编写单元测试用例。我不断遇到错误TypeError:无法读取未定义的属性'then'

下面是我的动作创建者:

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

请帮助

reactjs jestjs enzyme redux-async-actions
1个回答
0
投票

通过分派您的LoginActions.login()操作返回的最终结果是void(或undefined)。不是Promise,因此您无法在测试中调用.then()

根据测试代码判断,您将fetch-mock用于fetchMock。在测试商店已调度正确的操作之前,您应该可以wait for that to finish

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(),以便您can对其进行测试。是否应该取决于调整应用程序以处理该问题的工作量,因为您不希望应用程序因登录失败而出现任何未处理的承诺拒绝错误而崩溃。

© www.soinside.com 2019 - 2024. All rights reserved.