javascript 如何在Jest中正确模拟fs.readFileSync()?

7xllpg7q  于 2023-03-11  发布在  Java
关注(0)|答案(2)|浏览(221)

我正在使用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");

我可能错误的逻辑告诉我,它应该正确地模拟原始的字符串导入,并将其替换为“test string”字符串。然而,在运行测试时,它抛出:
TypeError:无法读取未定义的属性“toString”
我理解这意味着模拟没有成功,因为它应该成功地在字符串示例上调用.toString()。
我在这里做错了什么?

dxxyhpgq

dxxyhpgq1#

您不需要为jest.mock('fs')显式提供模块工厂参数。jest.mock()在需要时使用自动模拟版本模拟模块。这意味着fs.readFileSync是一个模拟方法,与jest.fn()相同。
您需要确保在模拟返回值之后请求被测模块,因为模块作用域中的代码将在需要时立即执行。
例如
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"
hwamh0ep

hwamh0ep2#

我的一个函数调用fs.readFileSync,所以我想stub 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();
});

相关问题