首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何使用jest在ES6模块中模拟变量,使实际函数以模拟值运行

如何使用jest在ES6模块中模拟变量,使实际函数以模拟值运行
EN

Stack Overflow用户
提问于 2021-06-29 13:45:17
回答 2查看 1.9K关注 0票数 0

下面是我想测试函数buttonReducer的示例代码。但是还原器函数中的大小写名是在另一个函数中生成的。因此,当我想单独测试还原器时,我希望覆盖RESET_TYPE、FETCH_TYPE和SHOW_TYPE,以便能够测试所有的场景。

代码语言:javascript
运行
复制
//main reducer.js
import {getActionTypeName} from './functions';

export const RESET_TYPE = getActionTypeName('RESET');
export const FETCH_TYPE = getActionTypeName('RESET');
export const SHOW_TYPE = getActionTypeName('RESET');

const initialState = {
  name: 'John'
};

export const buttonReducer = (state = {...initialState}, action){
  switch(action.type){
    case RESET_TYPE: {
      const newState = {"some random change", ...initialState};
      return newState;
    }
    case FETCH_TYPE: {
      const newState = {"some random change", ...initialState};
      return newState;
    }
    case SHOW_TYPE: {
      const newState = {"some random change", ...initialState};
      return newState;
    }
    default: {
      return state;
    }
  }
}

以下是我尝试过的几件事:

1.

代码语言:javascript
运行
复制
jest.mock('./functions', ()=> {
    return {
        getActionTypeName: ()=>('return whatever I want')
    }
}

但这不管用。

  1. 我完全知道使用redux-模拟商店运行整个应用程序。但是我特别想要的是,只是覆盖现有的变量,这样我就可以对一个函数进行场景测试了。

因此,本质上,我希望通过更改变量的值来运行还原器,而不仅仅是为了测试用例而模拟它们。

EN

回答 2

Stack Overflow用户

发布于 2021-06-30 04:42:28

由于操作类型RESET_TYPEFETCH_TYPESHOW_TYPE是在运行时在模块范围内定义和计算的,为了消除模块import的缓存效果,需要使用jest.resetModules()方法。在执行测试用例之前,我们需要调用它。这样我们就可以得到一个有新模块变量的新模块。这样可以防止测试用例相互影响。

现在,我们可以使用jest.doMock(moduleName,工厂,选项)MockFn.mockReturnValueOnce(价值)方法来模拟每个测试用例具有不同返回值的./functions模块和getActionTypeName函数。

例如。

reducer.js

代码语言:javascript
运行
复制
import { getActionTypeName } from './functions';

export const RESET_TYPE = getActionTypeName('RESET');
export const FETCH_TYPE = getActionTypeName('RESET');
export const SHOW_TYPE = getActionTypeName('RESET');

const initialState = {
  name: 'John',
};

export const buttonReducer = (state = { ...initialState }, action) => {
  switch (action.type) {
    case RESET_TYPE: {
      const newState = { a: 'a', ...initialState };
      return newState;
    }
    case FETCH_TYPE: {
      const newState = { b: 'b', ...initialState };
      return newState;
    }
    case SHOW_TYPE: {
      const newState = { c: 'c', ...initialState };
      return newState;
    }
    default: {
      return state;
    }
  }
};

functions.js

代码语言:javascript
运行
复制
export function getActionTypeName() {
  console.log('real implementation');
}

reducer.test.js

代码语言:javascript
运行
复制
describe('68179950', () => {
  beforeEach(() => {
    jest.resetModules();
  });
  it('should return dynamic RESET_TYPE', () => {
    jest.doMock('./functions', () => ({
      getActionTypeName: jest.fn().mockReturnValueOnce('RUNTIME_RESET_TYPE'),
    }));
    const { buttonReducer } = require('./reducer');
    const actual = buttonReducer({}, { type: 'RUNTIME_RESET_TYPE' });
    expect(actual).toEqual({ name: 'John', a: 'a' });
  });

  it('should return dynamic FETCH_TYPE', () => {
    jest.doMock('./functions', () => ({
      getActionTypeName: jest.fn().mockReturnValueOnce('RUNTIME_RESET_TYPE').mockReturnValueOnce('RUNTIME_FETCH_TYPE'),
    }));
    const { buttonReducer } = require('./reducer');
    const actual = buttonReducer({}, { type: 'RUNTIME_FETCH_TYPE' });
    expect(actual).toEqual({ name: 'John', b: 'b' });
  });

  it('should return dynamic SHOW_TYPE', () => {
    jest.doMock('./functions', () => ({
      getActionTypeName: jest
        .fn()
        .mockReturnValueOnce('RUNTIME_RESET_TYPE')
        .mockReturnValueOnce('RUNTIME_FETCH_TYPE')
        .mockReturnValueOnce('RUNTIME_SHOW_TYPE'),
    }));
    const { buttonReducer } = require('./reducer');
    const actual = buttonReducer({}, { type: 'RUNTIME_SHOW_TYPE' });
    expect(actual).toEqual({ name: 'John', c: 'c' });
  });
});

单元测试结果:

代码语言:javascript
运行
复制
 PASS  examples/68179950/reducer.test.js (18.013 s)
  68179950
    ✓ should return dynamic RESET_TYPE (12582 ms)
    ✓ should return dynamic FETCH_TYPE (1 ms)
    ✓ should return dynamic SHOW_TYPE (7 ms)

------------|---------|----------|---------|---------|-------------------
File        | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
------------|---------|----------|---------|---------|-------------------
All files   |   93.33 |       60 |     100 |   92.86 |                   
 reducer.js |   93.33 |       60 |     100 |   92.86 | 26                
------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       3 passed, 3 total
Snapshots:   0 total
Time:        22.095 s
票数 1
EN

Stack Overflow用户

发布于 2022-08-18 19:58:57

您可以让模拟返回一个jest fn,稍后可以更改返回值。这样你就不用每次都做一个新的模拟了。

代码语言:javascript
运行
复制
const getActionTypeName = jest.fn(() => {});

jest.mock('./pathToModule', () => {
  return {
    __esModule: true,
    getActionTypeName: () => getActionTypeName(),
  }
})

describe('functionBeingTested', () => {
  it('should do something', () => {
    getActionTypeName.mockReturnValue('RUNTIME_RESET_TYPE');
    // test code...
    // assertions...
  });
});
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68179950

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档