我正在使用fs模块将一个html字符串导入到我的模块中,如下所示:
const fs = require('fs');
const htmlString = fs.readFileSync("../utils/htmlString.html").toString();
然后,在我的测试文件中,我试图模拟fs模块,如下所示:
const fs = require('fs');
jest.mock("fs", () => {
return {
readFileSync: jest.fn()
}
})
fs.readFileSync.mockReturnValue("test string");
我可能错误的逻辑告诉我,它应该正确地模仿原始字符串导入,并将其替换为";测试串";一串然而,在运行测试时,它抛出:
TypeError:无法读取未定义的属性"toString">
我知道这意味着mock不成功,因为它应该在字符串实例上成功调用.toString((。
我在这里做错了什么?
您不需要为jest.mock('fs')
显式提供模块工厂参数。jest.mock()
在需要时使用自动模拟版本模拟模块。这意味着fs.readFileSync
是一个与jest.fn()
相同的mock方法。
您需要确保在模拟返回值后需要测试中的模块,因为模块范围内的代码将在需要时立即执行。
例如
index.js
:
const fs = require('fs');
const htmlString = fs.readFileSync('../utils/htmlString.html').toString();
console.log('htmlString: ', htmlString);
index.test.js
:
const fs = require('fs');
jest.mock('fs');
describe('70760704', () => {
test('should pass', () => {
expect(jest.isMockFunction(fs.readFileSync)).toBeTruthy();
fs.readFileSync.mockReturnValue('test string');
require('./');
});
});
测试结果:
PASS stackoverflow/70760704/index.test.js (7.242 s)
70760704
✓ should pass (14 ms)
console.log
htmlString: test string
at Object.<anonymous> (stackoverflow/70760704/index.js:3:9)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 7.279 s, estimated 8 s
jest.config.js
:
module.exports = {
testEnvironment: 'node',
};
软件包版本:
"jest": "^26.6.3"
我的一个函数调用fs.readFileSync
,所以我想存根readFileSync
,这样它就会在我的一次Jest测试中抛出错误。以下是我所做的:
utils.ts
:
import { readFileSync } from 'fs';
export const myFunc() {
...
try {
data = readFileSync("path/to/file.json", { encoding: 'utf-8' });
} catch (e) {
console.warn("Error", e);
return undefined;
}
...
}
utils.test.ts
:
import { myFunc } from 'lib/utils'
import * as fs from "fs"; // or const fs = require("fs");
test("my test", () => {
jest.spyOn(fs, "readFileSync").mockImplementationOnce(func => {
throw new Error("Mock file read error.");
});
const retVal = myFunc();
expect(retVal).toBeUndefined();
});