为打字稿中的符号创建模拟

问题描述 投票:0回答:1

假设我有一个组件:

export class Component {
  constructor(@injectable(IDependency) dep: IDependency) {}

  // other methods/properties do not matter
}

其所需的依赖定义为:

export const IDependency = Symbol('IDependency');
export interface IDependency { /* does not matter */ }

现在我想对组件进行单元测试,但由于依赖项的数量可能很大(不像 20 个,但 5 对我来说已经很重要了),我不想手动创建所有必需的模拟。相反,我希望 IoC 容器自动模拟任何未显式注册的内容。到目前为止还好吗?

我收到了符号(

IDependency
)并且需要创建界面的模拟(
IDependency
)。但是是否有可能将符号映射到打字稿中同名的接口?我想不会,否则一开始就不需要符号了。

如果没有,任何聪明的头脑可以提出解决方法吗?就像在编译时的某个地方存储有关接口的信息及其到符号的映射,以便可以在运行时模拟它?或者,也许使用非常通用的代理,以至于他们不关心他们正在嘲笑什么类型?

typescript unit-testing mocking inversion-of-control
1个回答
0
投票

我采用了第二种方法(当我发布问题时才想到这种方法),我的测试现在看起来像这样:

testSuiteFor(TestExplorer, function() {
  this.test('should send init request when ILanguageClient is ready', function() {
    const client = this.mock<ILanguageClient>(ILanguageClient);
    const readyCallback = captor<Function>();

    this.mock<IExtensionContext>(IExtensionContext, { subscriptions: [] });
    this.component();

    expect(client.onReady).toHaveBeenCalledWith(readyCallback);
    expect(client.sendRequest).not.toHaveBeenCalled();

    readyCallback.value();

    expect(client.sendRequest).toHaveBeenCalledWith("ut/explorer/init");
  });

  this.test('should register Run profile', function() {
    this.mock<IExtensionContext>(IExtensionContext, { subscriptions: [] });

    const controller = this.mock<ITestController>(ITestController);
    const explorer = this.component();

    expect(controller.createRunProfile).toHaveBeenCalledWith(
     "Run", 
     vscode.TestRunProfileKind.Run, 
     functionBoundTo(explorer.runTests)
    );
  });
});

今天我还偶然发现了typescript-rtti。我想我接下来会尝试一下。

© www.soinside.com 2019 - 2024. All rights reserved.