store.dispatch无法读取未定义的属性“ then”

时间:2019-11-11 14:12:12

标签: reactjs testing jestjs

我正在尝试测试我的async动作,但出现此错误:

  

store.dispatch无法读取未定义的属性'then'

我尝试在then上使用actionTypes(很抱歉,这是一个actionCreator,但我将其导入为actionType),但它源自{ {1}}至:

  

TypeError:actionTypes.fetchGitHubDataAsync(...)。那么它不是一个函数。

undefined

动作js文件

it('Dispatches BOOKS_SUCCESS after fetching books', () => {
   // Response body sample
   const mockData = [
   {
       "name": "javascript",
       "display_name": "JavaScript",
       "short_description": "JavaScript (JS) is a lightweight interpreted programming language with first-class functions.",
       "description": "JavaScript (JS) is a lightweight interpreted or JIT-compiled programming language with first-class functions. While it is most well-known as the scripting language for Web pages, many non-browser environments also use it, such as Node.js, Apache CouchDB and Adobe Acrobat. JavaScript is a prototype-based, multi-paradigm, dynamic language, supporting object-oriented, imperative, and declarative (e.g. functional programming) styles.",
       "created_by": "Brendan Eich",
       "released": "December 4, 1995",
       "created_at": "2016-11-28T18:41:00Z",
       "updated_at": "2019-11-06T15:05:24Z",
       "featured": true,
       "curated": true,
       "score": 7954.724
   }
   ]

   fetchMock.getOnce('https://api.github.com/search/topics?q=javascript',
                { body: { results: mockData }})

   const expectedActions = [
         { type: actionTypes.FETCH_GITHUB_DATA},
   ]
   store.dispatch(actionTypes.fetchGitHubDataAsync())
             .then(() => {
                 expect(store.getActions()).toEqual(expectedActions)
   })
})

1 个答案:

答案 0 :(得分:0)

这是一个不使用第三方模拟库的单元测试工作示例。

action.js

export const fetchGitHubDataAsync = () => {
  return dispatch => {
    return fetch('https://api.github.com/search/topics?q=javascript', {
      headers: {
        Accept: 'application/vnd.github.mercy-preview+json'
      }
    })
      .then(res => res.json())
      .then(json => {
        console.log('json', json.items.slice(0, 5));
        return dispatch({ type: 'FETCH_GITHUB_DATA', payload: json.items.slice(0, 5) });
      });
  };
};

action.spec.js

import * as actionTypes from './action';
import createMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';

const mws = [thunk];
const mockStore = createMockStore(mws);
const store = mockStore({});

describe('fetchGitHubDataAsync', () => {
  it('Dispatches BOOKS_SUCCESS after fetching books', () => {
    expect.assertions(2);
    const mJson = { items: [1, 2, 3, 4, 5, 6] };
    const mResponse = { json: jest.fn().mockResolvedValueOnce(mJson) };
    global.fetch = jest.fn().mockResolvedValueOnce(mResponse);
    const expectedActions = [{ type: 'FETCH_GITHUB_DATA', payload: [1, 2, 3, 4, 5] }];
    return store.dispatch(actionTypes.fetchGitHubDataAsync()).then(() => {
      expect(store.getActions()).toEqual(expectedActions);
      expect(global.fetch).toBeCalledWith('https://api.github.com/search/topics?q=javascript', {
        headers: {
          Accept: 'application/vnd.github.mercy-preview+json'
        }
      });
    });
  });
});

覆盖率100%的单元测试结果:

 PASS  src/stackoverflow/58803026/action.spec.js
  fetchGitHubDataAsync
    ✓ Dispatches BOOKS_SUCCESS after fetching books (16ms)

  console.log src/stackoverflow/58803026/action.js:239
    json [ 1, 2, 3, 4, 5 ]

-----------|----------|----------|----------|----------|-------------------|
File       |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
-----------|----------|----------|----------|----------|-------------------|
All files  |      100 |      100 |      100 |      100 |                   |
 action.js |      100 |      100 |      100 |      100 |                   |
-----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        5.329s, estimated 15s

源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/58803026