使用Jest in React的异步动作创建者测试用例

时间:2018-12-26 07:31:03

标签: javascript reactjs redux react-redux

我是writing the test cases的新手。在这里,我有一个动作创建者,就像

export function fetchUserJd() {
  return (dispatch) => {
    let url = FETCH_JD_ROOT_URL + page + "&" + size;
    dispatch({
      type: REQUEST_INITIATED
    })
    get(url)
      .then((response) => {
        console.log("response data",response.payload)
        if (response.status === 200) {
          dispatch({
            type: REQUEST_SUCCESSED,
          });
          dispatch({
            type: FETCHING_JOBDESCRIPTION_SUCCESS,
            data: response.payload,
          }
          )
        }
        else {
          dispatch({
            type: REQUEST_SUCCESSED
          })
          toastr.error("Error while fetching Job Description, Please check again");
          if (response.status === "") {
            toastr.error('Our server is down. Please check again');
          }
          dispatch({
            type: FETCHING_JOBDESCRIPTION_FAILED,
            data: response.status,
          });
          if (response.status === 401) {
            toastr.error('Please Login Again');
            localStorage.clear();
            history.push('/');
          }
        }
      })
  }
};

因此,我在这里尝试为此编写测试用例。

所以,我尝试过的是,

beforeEach(function () {
    moxios.install();
  });

  afterEach(function () {
    moxios.uninstall();
  });

  it('creates GET_POSTS_SUCCESS after successfuly fetching postse', () => {
    moxios.wait(() => {
      const request = moxios.requests.mostRecent();
      console.log("request is",request);
      request.respondWith({
        status: 200,
        response: dataResponse,
      });
    });

    const expectedActions = [
      { type: 'FETCHING_JOBDESCRIPTION_SUCCESS', data: dataResponse },
    ];

    const store = mockStore({ data: {} })

    return store.dispatch(actions.fetchUserJd()).then(() => {
      // return of async actions
      expect(store.getActions()).toEqual(expectedActions);
    });
  });

现在,我遇到了这样的错误,

● Header component actions › creates GET_POSTS_SUCCESS after successfuly fetching postse

    TypeError: Cannot read property 'then' of undefined

      at Object.it (src/modules/header/actions/_tests_/index.test.js:64:53)
      at Promise.resolve.then.el (node_modules/p-map/index.js:46:16)
      at process._tickCallback (internal/process/next_tick.js:109:7)

现在,我实际上不明白为什么会出现此错误。

我正在调用一个动作,然后检查是否正在调用预期的动作。

export const get = (url) =>
    axios.get(
        url,
        {
            headers: {
                "Authorization": localStorage.getItem("access_token") !== null ? `Bearer ` + localStorage.getItem("access_token") : null,
                "Content-Type": "application/json"
            }
        }
    ).then(data => {
        if (data.status === HttpStatus.OK) {
            return {
                status: data.status,
                payload: data.data
            };
        }
    }).catch(err => {
        return {
            status: err.response.data,
            payload: null
        };
    });

那么,有人可以帮助我解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

我认为您的错误来自此处,但这不是问题。

return store.dispatch(actions.fetchUserJd()).then(() => {
  // return of async actions
  expect(store.getActions()).toEqual(expectedActions);
});

这部分代码尝试使用dispatch的“ then”功能(目前不返回Promise)。它不会返回承诺。最初对actions.fetchUserJd()的调用没有任何异步行为,它返回一个有权访问分派的函数,该函数进行API调用(异步),但处理 .then() 内部,不会返回。

这意味着能够等待它完成。您可以像承诺mocking async actions 的示例一样将行动的回报作为一个承诺。

下面是他的例子

function fetchData () {
  return dispatch => {
    return fetch('/users.json') // Here returning the .then() of the fetch(equivalent of your get) is returning a promise, that's why for him the .then() call on the dispatch works in his tests !
      .then(() => dispatch(success()))
  };
}

然后您可以使用原始代码。

return store.dispatch(actions.fetchUserJd()).then(() => {
  // return of async actions
  expect(store.getActions()).toEqual(expectedActions);
});

完全不相关的一点是,您不会在操作中直接使用被get调用拒绝的处理函数。 例如:

get('http://localhost:3000/example')
   .then(
   (successData) => {
       // Do whatever you want to in case of positive resolution of the get call...
       // Will contain your response code and your data.
    },
    (rejectData) => {
       // Do whatever you want if the request fails, its error data is caught inside rejectData
    }
)