如何重构调用函数的函数,以便使用typescript和sinon对其进行测试



我有以下代码

import {
getIndexDocument
} from "@assets";
class MetaController {

public async exploreIndexDocument(): Promise<Asset | undefined> {
const {
result: { assignedDirectories }
} = await getIndexDocument(this._serviceConfig).catch(err => {
throw new Error(`[AssetsController] Bad response on discovering index doc because ${err}`);
});
}
}

正如您所看到的,exploreIndexDocument正在调用函数getIndexDocument。我想为exploreIndexDocument编写一个测试,但我不能使用sinon存根getIndexDocument,因为sinon不允许您存根函数。我如何构建这个类来做到这一点?

您需要某种注入存根的方法,以便您的类实例调用存根而不是外部库。这个答案阐述了一些备选方案。注入存根的替代方法是替换正在导入的整个模块。这是使用链接接缝调用的。这个答案显示了一种方法,并列出了各种模块加载器来帮助您做到这一点

就我个人而言,我已经慢慢地放弃了模块嘲讽技术,并试图让自己留在依赖注入的领域(备选方案1(,因为无论底层环境如何,这都是有效的,而且任何刚开始的程序员都可以阅读测试。侵入性最小的方法可能就是这样:

import {
getIndexDocument
} from "@assets";
class MetaController {
private getIndexDocument: (config:object) => Promise<{assignedDirectories:any> };
constructor(deps = {getIndexDocument}) {
this.getIndexDocument = getIndexDocument;
}

public async exploreIndexDocument(): Promise<Asset | undefined> {
const {
result: { assignedDirectories }
} = await this.getIndexDocument(this._serviceConfig).catch(err => {
throw new Error(`[AssetsController] Bad response on discovering index doc because ${err}`);
});
}
}

你现在可以很容易地测试这个:

const fake = sinon.fake.resolves({ assignedDirectories: ['/foo/dir'] });
const controller = new MetaController({getIndexDocument: fake});
const promise = controller.exploreIndexDocument();
expect(fake.calledOnce).toBe(true);
// further assertions follow ... see https://sinonjs.org/releases/latest/fakes/

最新更新