如何在单独导入的函数上使用jest.fn()

时间:2019-08-02 15:50:58

标签: redux jestjs

我在模拟将单个导入的函数调用到我的测试时遇到麻烦。该测试是一个简单的函数,我将其放入Redux动作中,以便能够根据条件设置变量。

这是Body.duck.js中的函数:

export const getCurrentOrPrevSelection = isExecutedFromPagination => (dispatch, getState) => {
  const {
    editor: { selection },
    body: { queryRequest },
  } = getState();

  if (isExecutedFromPagination && queryRequest.breadcrumb) {
    const {
      query: { branch, includeSplits, primaryFa, split, isInitial },
    } = queryRequest.breadcrumb;
    return {
      branch,
      includeSplits,
      primaryFa,
      split,
      isInitial,
    };
  }
  return selection;
};

这是测试文件:

import reudcer, { ...other exported functions, getCurrentOrPrevSelection } from '../Body.duck';

it ('should use selection in breadcrumb state when fetching new data from pagination action', () => {
    let isExecutedFromPagination = false;
    const bodyState = {
      ...initialState.body,
      queryRequest: {
        ...initialState.body.queryRequest,
        breadcrumb: {
          ...initialState.body.breadcrumb,
          query: {
            name: 'Full Book Performance',
            branch: null,
            includeSplits: true,
            primaryFa: 'AXFO',
            split: null,
            isInitial: true,
          },
        },
      },
    };
    const selection = {
      branch: null,
      includeSplits: true,
      primaryFa: 'AXFO',
      split: null,
      isInitial: true,
    };

    expect(getCurrentOrPrevSelection(isExecutedFromPagination)(jest.fn(), () => ({
      body: { ...bodyState },
      editor: { faidSelection },
    }))).toHaveReturnedWith({
      branch: null,
      includeSplits: true,
      primaryFa: 'AXFO',
      split: null,
      isInitial: true,
    });
  });

如果我不包括对getCurrentOrPrevSelection的任何模拟引用,则会在下面收到此错误,但它会按预期返回正确的值:

    expect(jest.fn())[.not].toHaveReturnedWith()

    jest.fn() value must be a mock function or spy.
    Received:
      object: {"branch": null, "includeSplits": true, "isInitial": true, "primaryFa": "AXFO", "split": null}

如果我做类似getCurrentOrPrevFaidSelection = jest.fn();的操作,则会收到一条错误消息,提示getCurrentOrPrevFaidSelection is read-only

在这里我可以做些什么?

1 个答案:

答案 0 :(得分:0)

您要测试此功能。因此,您无需嘲笑。

只需调用函数并使用expect().toEqualexpect().toMatchObject验证结果即可。

expect(getCurrentOrPrevSelection(isExecutedFromPagination)(.....)).toMatchObject({
      branch: null,
      ...
    });

直接将jest.fn()作为参数也没有意义:您无法验证它是否已被调用或提供模拟返回。

const dispatchMock = jest.fn();
expect(getCurrentOrPrevSelection(isExecutedFromPagination)(dispatchMock, ....);
expect(dispatchMock).toHaveBeenCalledWith(...)

一旦不希望像您在示例中那样调用它,则最好显式提供noop函数() => {}而不是jest.fn()。这样,您就可以使它变得明确,因此,如果可以预期没有针对此函数的断言,则不会有人感到困惑。

Offtop:实际上,这并不是测试redux动作创建者的好方法。看到您实际测试实施细节。如果您从redux-thunk迁移到redux-sagaredux-loop怎么办?还是将单个动作分成2个以获得更好的灵活性?现在,这意味着您必须重写所有测试。

如果您不是将测试动作创建者单独隔离,而是将动作连接到真实(而非模拟)商店怎么办?您可以调度操作(在对外部API进行模拟调用之后)并验证商店的状态。