模拟一个模块中的单个函数,该模块也从另一个函数调用它,例如jest、typescript



我有两个功能模块:


export const functionReturnsOne = () => {
return 1;
};
export const functionReturnsTwo = () => {
return functionReturnsOne() + functionReturnsOne();
};

现在我想模拟functionReturnsOne,但保留原始的functionReturnsTwo

以下是测试:

import { functionReturnsTwo, functionReturnsOne } from '../testModule';
jest.mock('../testModule', () => {
const actualTestModule = jest.requireActual('../testModule');
return {
...actualTestModule,
functionReturnsOne: jest.fn()
};
});
describe('testModule', () => {
test('when functionReturnsOne is mocked but functionReturnsTwo is not', () => {
const mockFunctionReturnsOne = functionReturnsOne as jest.Mock;
mockFunctionReturnsOne.mockReturnValue(13);
const result1 = functionReturnsOne();
const result2 = functionReturnsTwo();
expect(result1).toBe(13);
expect(result2).toBe(26);
});
});

运行测试后,result1按预期包含13,因此functionReturnsOne的mock起作用。但result2包含2,这意味着这个函数调用了functionReturnsOne的非模拟版本。

有没有一种优雅的方法(不拆分成单独的文件,也不注入依赖项(来调用原始的functionReturnsTwo,它将调用functionReturnsOne的模拟版本?

根据本评论中提供的建议,以下内容对我有效:

import * as testModule from "../testModule";
describe('test spyon with function expressions', function () {
test('when there is no mock', () => {
jest.spyOn(testModule, 'functionReturnsOne').mockReturnValue(13);
const result1 = testModule.functionReturnsOne();
const result2 = testModule.functionReturnsTwo();
expect(result1).toBe(13);
expect(result2).toBe(26);
});
});

package.json(根据要求(

{
"name": "cookbook",
"version": "1.0.0",
"description": "A simple recipe app using typescript and sequelize",
"main": "dist/index.js",
"scripts": {
"test": "jest",
"dev": "nodemon src/index.ts",
"build": "npx tsc"
},
"keywords": [
"sequelize",
"typescript",
"food",
"recipes",
"cache",
"speed",
"microdiff"
],
"author": "ibywaks",
"license": "ISC",
"dependencies": {
"dotenv": "^10.0.0",
"express": "^4.17.1",
"lodash": "^4.17.21",
"microdiff": "^1.3.0",
"mysql2": "^2.2.5",
"node-cache": "^5.1.2",
"sequelize": "^6.6.4"
},
"devDependencies": {
"@types/express": "^4.17.12",
"@types/jest": "^27.0.2",
"@types/lodash": "^4.14.171",
"@types/node": "^15.12.4",
"@types/node-cache": "^4.2.5",
"@types/supertest": "^2.0.11",
"eslint": "^7.30.0",
"jest": "^27.2.4",
"nodemon": "^2.0.7",
"supertest": "^6.1.6",
"ts-jest": "^27.0.5",
"ts-node": "^10.0.0",
"typescript": "^4.3.4"
}
}

由于您只在函数一中返回mock值,因此原始函数Two没有必要获得mock输入。试着这样模拟functionTwo并得到所需的响应。

import { functionReturnsTwo, functionReturnsOne } from '../testModule';
jest.mock('../testModule', () => {
const actualTestModule = jest.requireActual('../testModule');
return {
...actualTestModule,
functionReturnsOne: jest.fn()
};
});
describe('testModule', () => {
test('when there is no mock', () => {
const mockFunctionReturnsOne = functionReturnsOne as jest.Mock;
mockFunctionReturnsOne.mockReturnValue(13);
const mockFunctionReturnsTwo = functionReturnsTwo as jest.Mock;
mockFunctionReturnsTwo.mockReturnValue(functionReturnsOne() + 
functionReturnsOne());

const result1 = functionReturnsOne();
const result2 = functionReturnsTwo();
expect(result1).toBe(13);
expect(result2).toBe(26);
});
});

最新更新