Node.js 来自另一个文件的Jest模拟嵌套函数
我正在学习点头和开玩笑。我在单元测试方面遇到了问题。我只是把我的实际代码翻译成一个简单的逻辑。我有两个文件如下Node.js 来自另一个文件的Jest模拟嵌套函数,node.js,unit-testing,jestjs,mocking,Node.js,Unit Testing,Jestjs,Mocking,我正在学习点头和开玩笑。我在单元测试方面遇到了问题。我只是把我的实际代码翻译成一个简单的逻辑。我有两个文件如下 // age.js function getAge(birthYear) { const age = 2021-birthYear; return age } module.exports = { getAge } 我希望从getAge接收99,但它返回null。谢谢你的帮助。谢谢。下面的示例使用的“笑话”:“^26.6.3” user.js: const{getA
// age.js
function getAge(birthYear) {
const age = 2021-birthYear;
return age
}
module.exports = { getAge }
我希望从getAge
接收99,但它返回null
。谢谢你的帮助。谢谢。下面的示例使用的“笑话”:“^26.6.3”
user.js
:
const{getAge}=require('./age');
异步函数isMinor(){
const bYear=1991;
const age=等待获取(bYear);
console.log('age:',age);
如果(年龄){
在每个之前(()=>{
开玩笑('./年龄',()=>({
getAge:jest.fn(()=>99),
}));
});
测试('应该是成年人',异步()=>{
const{isMinor}=require('./user');
const{getAge}=require('./age');
const actual=wait isMinor();
expect(实际).toBeFalsy();
expect(getAge),toBeCalledWith(1991);
});
});
单元测试结果:
PASS examples/66288290/user.test.js
Age Test
✓ should be an adult (1911 ms)
console.log
age: 99
at examples/66288290/user.js:6:11
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 87.5 | 50 | 100 | 87.5 |
user.js | 87.5 | 50 | 100 | 87.5 | 8
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 3.197 s
PASS examples/66288290/user.test.js
Age Test
✓ should be an adult (11 ms)
console.log
age: 99
at examples/66288290/user.js:6:11
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 87.5 | 50 | 100 | 87.5 |
user.js | 87.5 | 50 | 100 | 87.5 | 8
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 3.502 s
选项2:在模块作用域中使用jest.mock()
,它将被提升到代码顶部。即使您需要文件顶部的模块。您需要的/age
模块已经被模拟
const{isMinor}=require('./user');
const{getAge}=require('./age');
开玩笑('./年龄',()=>({
getAge:jest.fn(()=>99),
}));
描述('年龄测试',()=>{
毕竟(()=>{
jest.resetAllMocks();
});
测试('应该是成年人',异步()=>{
const actual=wait isMinor();
expect(实际).toBeFalsy();
expect(getAge),toBeCalledWith(1991);
});
});
单元测试结果:
PASS examples/66288290/user.test.js
Age Test
✓ should be an adult (1911 ms)
console.log
age: 99
at examples/66288290/user.js:6:11
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 87.5 | 50 | 100 | 87.5 |
user.js | 87.5 | 50 | 100 | 87.5 | 8
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 3.197 s
PASS examples/66288290/user.test.js
Age Test
✓ should be an adult (11 ms)
console.log
age: 99
at examples/66288290/user.js:6:11
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 87.5 | 50 | 100 | 87.5 |
user.js | 87.5 | 50 | 100 | 87.5 | 8
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 3.502 s
下面的示例使用了“jest”:“^26.6.3”
user.js
:
const{getAge}=require('./age');
异步函数isMinor(){
const bYear=1991;
const age=等待获取(bYear);
console.log('age:',age);
如果(年龄){
在每个之前(()=>{
开玩笑('./年龄',()=>({
getAge:jest.fn(()=>99),
}));
});
测试('应该是成年人',异步()=>{
const{isMinor}=require('./user');
const{getAge}=require('./age');
const actual=wait isMinor();
expect(实际).toBeFalsy();
expect(getAge),toBeCalledWith(1991);
});
});
单元测试结果:
PASS examples/66288290/user.test.js
Age Test
✓ should be an adult (1911 ms)
console.log
age: 99
at examples/66288290/user.js:6:11
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 87.5 | 50 | 100 | 87.5 |
user.js | 87.5 | 50 | 100 | 87.5 | 8
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 3.197 s
PASS examples/66288290/user.test.js
Age Test
✓ should be an adult (11 ms)
console.log
age: 99
at examples/66288290/user.js:6:11
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 87.5 | 50 | 100 | 87.5 |
user.js | 87.5 | 50 | 100 | 87.5 | 8
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 3.502 s
选项2:在模块作用域中使用jest.mock()
,它将被提升到代码顶部。即使您需要文件顶部的模块。您需要的/age
模块已经被模拟
const{isMinor}=require('./user');
const{getAge}=require('./age');
开玩笑('./年龄',()=>({
getAge:jest.fn(()=>99),
}));
描述('年龄测试',()=>{
毕竟(()=>{
jest.resetAllMocks();
});
测试('应该是成年人',异步()=>{
const actual=wait isMinor();
expect(实际).toBeFalsy();
expect(getAge),toBeCalledWith(1991);
});
});
单元测试结果:
PASS examples/66288290/user.test.js
Age Test
✓ should be an adult (1911 ms)
console.log
age: 99
at examples/66288290/user.js:6:11
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 87.5 | 50 | 100 | 87.5 |
user.js | 87.5 | 50 | 100 | 87.5 | 8
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 3.197 s
PASS examples/66288290/user.test.js
Age Test
✓ should be an adult (11 ms)
console.log
age: 99
at examples/66288290/user.js:6:11
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 87.5 | 50 | 100 | 87.5 |
user.js | 87.5 | 50 | 100 | 87.5 | 8
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 3.502 s
由于您只使用模拟值测试isMinor
,因此您需要使用多个值来测试它,以覆盖所有不同的场景(分支),因此只需调用以下命令即可为/age.js
创建一次模拟:
const { getAge } = require('./age');
jest.mock('./age');
它将仅为此测试文件为每个模块函数生成一个模拟函数
使用jest.mock模拟的模块仅针对调用jest.mock的文件进行模拟。导入该模块的另一个文件将获得原始实现,即使它在模拟该模块的测试文件之后运行
因此,您无需恢复原始实现
使用自动模拟的最大好处是当来自实现的方法(在本例中为getAge
)被删除时,测试将失败。
剩下要做的唯一一件事就是设置你想要测试的mock的返回值,因为它应该返回你应该使用的承诺
user.test.js
const { isMinor } = require("./user");
const { getAge } = require('./age');
jest.mock('./age');
describe("Age Test", () => {
describe('getAge returning more than 18', () => {
beforeAll(() => {
getAge.mockResolvedValue(99)
})
test("should be an adult", async () => {
expect(await isMinor()).toEqual(false);
});
})
describe('getAge returning less than 18', () => {
beforeAll(() => {
getAge.mockResolvedValue(13)
})
test("should be a minor", async () => {
expect(await isMinor()).toEqual(true);
});
})
});
由于您只使用模拟值测试isMinor
,因此您需要使用多个值来测试它,以覆盖所有不同的场景(分支),因此只需调用以下命令即可为/age.js
创建一次模拟:
const { getAge } = require('./age');
jest.mock('./age');
它将仅为此测试文件为每个模块函数生成一个模拟函数
使用jest.mock模拟的模块仅针对调用jest.mock的文件进行模拟。导入该模块的另一个文件将获得原始实现,即使它在模拟该模块的测试文件之后运行
因此,您无需恢复原始实现
使用自动模拟的最大好处是当来自实现的方法(在本例中为getAge
)被删除时,测试将失败。
剩下要做的唯一一件事就是设置你想要测试的mock的返回值,因为它应该返回你应该使用的承诺
user.test.js
const { isMinor } = require("./user");
const { getAge } = require('./age');
jest.mock('./age');
describe("Age Test", () => {
describe('getAge returning more than 18', () => {
beforeAll(() => {
getAge.mockResolvedValue(99)
})
test("should be an adult", async () => {
expect(await isMinor()).toEqual(false);
});
})
describe('getAge returning less than 18', () => {
beforeAll(() => {
getAge.mockResolvedValue(13)
})
test("should be a minor", async () => {
expect(await isMinor()).toEqual(true);
});
})
});
我认为在每个之前都应该有resetModules。选项1可以工作,因为它只导入了一次。Hi@slideshowp2。只是一个后续问题:如果getAge
和isMinor
在同一个文件中会怎么样?只有当我const{isMinor,getAge}=require(“./文件”)时,如何才能模拟getAge
?非常感谢much@Luke然后您需要执行jest.mock('./文件')
模拟/file
模块我认为每个模块之前都应该有resetModules。选项1可以工作,因为它只导入了一次。Hi@slideshowp2。只是一个后续问题:如果getAge
和isMinor
在同一个文件中怎么办?只有当我常量{isMinor,getAge}=require(“./file”)时,怎么才能模拟getAge
?非常感谢much@Luke然后您需要执行jest.mock('./file')
以模拟/file
模块