所以我的代码看起来像这样:
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这样的东西来允许依赖注入吗?我有一个init脚本,可以在应用程序正常运行时设置“默认值”,然后在测试中“覆盖”这些默认值?
在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!" }");
}
}));