【问题标题】:Jest mock not used - normal method is run instead未使用玩笑模拟 - 改为运行正常方法
【发布时间】:2018-04-10 13:25:18
【问题描述】:

我有以下设置来测试异步函数。

首先,我的文件夹结构:

src/
├── App.vue
├── api
│   ├── __mocks__
│   │   └── api.js
│   └── api.js
├── components
│   ├── ...
├── main.js
└── store
    ├── __tests__
    │   └── actions.spec.js
    ├── actions.js
    ├── getters.js
    ├── index.js
    ├── mutation-types.js
    └── mutations.js

然后我的actions.spec.js:

import * as types from '@/store/mutation-types';
import api from '@/api/api';
import {
  fetchItems,
  requestItems,
  saveQuestion,
  vote,
} from '../actions';

jest.mock('@api/api');

describe('fetchItems Action', () => {
  let state;
  let commit;
  let dispatch;
  beforeAll(() => {
    commit = jest.fn();
    dispatch = jest.fn();
    state = {
      apiEntryPoint: '',
      nextPage: 0,
    };
  });

  beforeEach(() => {
    fetchItems({
      commit,
      dispatch,
      state,
    });
  });

  it('should call a commit before fetching', () => {
    expect(commit).toHaveBeenCalledWith(types.PRE_HTTP_REQUEST);
  });

  it('should call receiveItems after succesful fetch', () => {
    setTimeout(() => {
      expect(dispatch).toHaveBeenCalledWith('receiveItems', {});
    });
  });

  it('should call a fail commit if request fails', () => {
    api.fetchItems = jest.fn(() => Promise.reject());
    setTimeout(() => {
      expect(commit).toHaveBeenCalledWith(types.FETCHED_ADS_FAIL);
    });
  });
});

api/api.js

import axios from 'axios';

axios.defaults.baseURL = 'https://polls.apiblueprint.org/';

const getUrl = () => (
  axios('/')
    .then(response => response.data.questions_url)
    .catch((err) => {
      throw err;
    })
);

const fetchItems = (url, page = 1) => (
  axios(url, { params: { page } })
    .then(response => response.data)
    .catch((err) => {
      throw err;
    })
);
export default {
  fetchItems, getUrl,
};

还有api/__mocks__/api.js

const getUrl = jest.fn(() => Promise.resolve());

const fetchItems = jest.fn(() => Promise.resolve());

export default {
  fetchItems, getUrl
};

我的问题:

  1. 通过使用调试器,它看起来不像在运行模拟方法
  2. 我的输出看起来像一个真正的 HTTP 请求完成了:

PASS src/components/QuestionsList/QuestionsList.spec.js 通过 src/components/Question/Question.spec.js (节点:48568)UnhandledPromiseRejectionWarning:未处理的承诺拒绝(拒绝 id:9):错误:错误:网络错误 (节点:48568)[DEP0018] DeprecationWarning:不推荐使用未处理的承诺拒绝。在未来,承诺拒绝是 未处理将以非零退出终止 Node.js 进程 代码。 (节点:48568)UnhandledPromiseRejectionWarning:未处理的承诺拒绝(拒绝 id:10):错误:错误:网络错误 通过 src/store/tests/actions.spec.js

  1. 即使我用其他随机参数更改“toHaveBeenCalledWith()”的参数,我的测试也通过了。

【问题讨论】:

    标签: vue.js jestjs


    【解决方案1】:

    在使用 setTimeout 的测试中,您需要使用 done 回调。

    目前,Jest 正在运行测试并在没有错误的情况下到达终点。对 Jest 来说,这意味着测试已经通过。让 Jest 异步运行测试的一种方法是使用 done 回调。

    如果测试有 done 回调,则在调用 done 回调之前,Jest 不会通过测试。

    您的代码应如下所示:

    it('should call a fail commit if request fails', (done) => {
      api.fetchItems = jest.fn(() => Promise.reject());
      setTimeout(() => {
        expect(commit).toHaveBeenCalledWith(types.FETCHED_ADS_FAIL);
        done()
      });
    });
    

    您可以在 Jest 文档 (http://facebook.github.io/jest/docs/en/asynchronous.html#callbacks) 中了解 [done 回调。

    Jest 还有其他几种处理asynchronous code 的方式。

    【讨论】:

      【解决方案2】:

      如果有人遇到这种情况并需要构建解决方案以在发生这种情况时失败,我已经解决了这个问题:Handle UnhandledPromiseRejectionWarning Errors

      【讨论】:

        猜你喜欢
        • 2019-03-23
        • 1970-01-01
        • 2022-12-15
        • 2018-10-29
        • 2019-04-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多