允许对 stub/mock fs 进行 mocha 测试的真实方法是什么,这样我就可以在不访问磁盘的情况下测试函数?

What is a real-world way of allowing a mocha test to stub/mock fs so I can test a function without it accessing the disk?

所以我的代码是这样的:

import FsAsyncFactory from '../fs/FsAsyncFactory'
import ObjectHelper from '../utils/ObjectHelper'
import Config from './Config'

export class ConfigHelper {

    // this is the function under test
    public static async primeCacheObj(): Promise<void> {

        const configFileObj: any = await ConfigHelper.getConfigFileObj()

    }

    private static configCacheObj: Config = null

    private static async getConfigFileObj(): Promise<any> {
        const fsAsync: any = FsAsyncFactory.getFsAsync()
        const fileContents: string = await fsAsync.readFileAsync('./config/hubnodeConfig.json')

        return JSON.parse(fileContents)
    }

}

export default ConfigHelper

让我的单元测试代码阻止它实际写入磁盘的最佳方法是什么?

我应该使用类似 InversifyJS 的东西来允许依赖注入吗?我有一个初始化脚本,可以设置 "defaults" 当应用程序正常时 运行 然后 "override" 测试中的那些默认值?

在JavaScript,传统上人们一直在使用monkey patching来编写单元测试。

我个人认为猴子修补是一种不好的做法,会导致代码无法维护。我更喜欢依赖注入,这就是我创建 InversifyJS 的原因。

您可以使用 InversifyJS 来 override bindings on unit tests

这意味着 ConfigHelper 将通过依赖注入获得 FsAsync 的实例。

@injectable()
export class ConfigHelper {

    @inject("FsAsync") private readonly _fsAsync: FsAsync;

    // this is the function under test
    public static async primeCacheObj(): Promise<void> {

        const configFileObj: any = await ConfigHelper.getConfigFileObj()

    }

    private static configCacheObj: Config = null

    private static async getConfigFileObj(): Promise<any> {
        const json = await this_fsAsync.readFileAsync('./xxx.json')
        return JSON.parse(json)
    }

}

在单元测试期间,您可以替换 FsAsync 类型绑定:

container.bind<FsAsync>("FsAsync")
         .toDynamicValue(() => FsAsyncFactory.getFsAsync());

注入模拟:

container.rebind<FsAsync>("FsAsync")
         .toDynamicValue(() => ({
             readFileAsync: (path) => {
                 return Promise.resolve("{ hardCodedJson: "happy days!" }");
             }
         }));