无法使用 Sinon 模拟节点 fs 模块
Unable to Mock Node fs Modules with Sinon
我无法正确模拟节点 fs
模块的 promises 方法。
我的 appData.ts
文件调用真正的 fs.promises.mkdir
方法而不是我在 \__tests__/appData.test.js
中声明的模拟方法。
我认为问题的出现是由于模拟方法如何嵌套在导入模块 fs
中作为 fs.promises.readdir
。但是我当然不确定。
我知道我应该能够调试这个问题,但我想我需要更有经验的人的帮助。
appData.ts
import * as fs from 'fs'
import { app } from 'electron'
const { readdir, mkdir } = fs.promises
/**
* Initialize app data dir.
* @param {string} path Where to initialize app data dir.
*/
export async function initDir(path: string): Promise<void> {
try {
await readdir(path)
console.log(`app data dir exists at ${path}`)
} catch (error) {
if (error.code === 'ENOENT') {
try {
await mkdir(path)
console.log(`created app data dir at ${path}`)
} catch (error) {
console.error(`could not create app data dir at ${path}`)
console.error(error)
app.quit()
}
} else {
console.error('unable to handle error while initializing app data dir')
console.error(error)
app.quit()
}
}
}
__tests__/appData.js
import * as appData from '../appData'
import { stub } from 'sinon'
import * as fs from 'fs'
require('chai').should()
describe('appData', () => {
describe('initDir()', () => {
it ('creates app data dir at passed path when it is missing', async () => {
const noentError = new Error()
noentError.code = 'ENOENT'
const readdirStub = stub(fs.promises, 'readdir').throws(noentError)
const mkdirStub = stub(fs.promises, 'mkdir').resolves(true)
const expected = 'a/b/c'
await appData.initDir(expected)
mkdirStub.args[0][0].should.equal(expected)
})
})
})
我找到了导致模拟无法工作的行。
appData.ts
...
const { readdir, mkdir } = fs.promises
...
这对我来说很有意义。考虑到当导入 appData.ts
时,fs.promises
被解构为 \__tests__/appData.test.js
无法触及的变量,我模拟 fs.promises
方法并不重要。
如果我想保留解构,我可以在initDir()
内完成。这允许 appData.ts
在 initDir
运行时访问模拟 \__tests__/appData.test.js
。
我无法正确模拟节点 fs
模块的 promises 方法。
我的 appData.ts
文件调用真正的 fs.promises.mkdir
方法而不是我在 \__tests__/appData.test.js
中声明的模拟方法。
我认为问题的出现是由于模拟方法如何嵌套在导入模块 fs
中作为 fs.promises.readdir
。但是我当然不确定。
我知道我应该能够调试这个问题,但我想我需要更有经验的人的帮助。
appData.ts
import * as fs from 'fs'
import { app } from 'electron'
const { readdir, mkdir } = fs.promises
/**
* Initialize app data dir.
* @param {string} path Where to initialize app data dir.
*/
export async function initDir(path: string): Promise<void> {
try {
await readdir(path)
console.log(`app data dir exists at ${path}`)
} catch (error) {
if (error.code === 'ENOENT') {
try {
await mkdir(path)
console.log(`created app data dir at ${path}`)
} catch (error) {
console.error(`could not create app data dir at ${path}`)
console.error(error)
app.quit()
}
} else {
console.error('unable to handle error while initializing app data dir')
console.error(error)
app.quit()
}
}
}
__tests__/appData.js
import * as appData from '../appData'
import { stub } from 'sinon'
import * as fs from 'fs'
require('chai').should()
describe('appData', () => {
describe('initDir()', () => {
it ('creates app data dir at passed path when it is missing', async () => {
const noentError = new Error()
noentError.code = 'ENOENT'
const readdirStub = stub(fs.promises, 'readdir').throws(noentError)
const mkdirStub = stub(fs.promises, 'mkdir').resolves(true)
const expected = 'a/b/c'
await appData.initDir(expected)
mkdirStub.args[0][0].should.equal(expected)
})
})
})
我找到了导致模拟无法工作的行。
appData.ts
...
const { readdir, mkdir } = fs.promises
...
这对我来说很有意义。考虑到当导入 appData.ts
时,fs.promises
被解构为 \__tests__/appData.test.js
无法触及的变量,我模拟 fs.promises
方法并不重要。
如果我想保留解构,我可以在initDir()
内完成。这允许 appData.ts
在 initDir
运行时访问模拟 \__tests__/appData.test.js
。