下面是我想测试函数buttonReducer的示例代码。但是还原器函数中的大小写名是在另一个函数中生成的。因此,当我想单独测试还原器时,我希望覆盖RESET_TYPE、FETCH_TYPE和SHOW_TYPE,以便能够测试所有的场景。
//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.
jest.mock('./functions', ()=> {
return {
getActionTypeName: ()=>('return whatever I want')
}
}
但这不管用。
因此,本质上,我希望通过更改变量的值来运行还原器,而不仅仅是为了测试用例而模拟它们。
发布于 2021-06-29 20:42:28
由于操作类型RESET_TYPE
、FETCH_TYPE
和SHOW_TYPE
是在运行时在模块范围内定义和计算的,为了消除模块import
的缓存效果,需要使用jest.resetModules()方法。在执行测试用例之前,我们需要调用它。这样我们就可以得到一个有新模块变量的新模块。这样可以防止测试用例相互影响。
现在,我们可以使用jest.doMock(moduleName,工厂,选项)和MockFn.mockReturnValueOnce(价值)方法来模拟每个测试用例具有不同返回值的./functions
模块和getActionTypeName
函数。
例如。
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 = { 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
export function getActionTypeName() {
console.log('real implementation');
}
reducer.test.js
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' });
});
});
单元测试结果:
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
发布于 2022-08-18 11:58:57
您可以让模拟返回一个jest fn,稍后可以更改返回值。这样你就不用每次都做一个新的模拟了。
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...
});
});
https://stackoverflow.com/questions/68179950
复制相似问题