我有两个功能模块:
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);
});
});