【问题标题】:How to test promise with try and catch a function like this example如何使用 try 和 catch 像这个示例这样的函数来测试 Promise
【发布时间】:2021-12-10 06:56:18
【问题描述】:

由于某种原因,我无法测试拒绝。这是功能,我想 100% 测试它。现在它像 92% 并且抱怨拒绝(e)没有测试..

  public resolve(): Promise<{ [key: string]: boolean }> {
    return new Promise<{ [key: string]: boolean }>(async (resolve, reject) => {
      try {
        for await (const setting of settings) {
          // ObjectStore that acts like hashMap
          this.store.set(setting.key, setting.value);
        }
        resolve();
      }
      catch (e) {
        reject(e);
      }
    });
  }

更新:

我必须制作另一个 Mock 才能使 catch 语句首先发生。 而且 TestBed.overrideProvider 并没有真正为我工作,所以我不得不

  it('should return a rejected promise', async() => {
    TestBed.resetTestingModule();
    TestBed.configureTestingModule({ 
//inserting the new mock provider to trigger the catch 
... 
});

然后使用下面的答案(谢谢@Apoorva Chikara)并为我工作

如果有更简单的方法,请告诉我

这是我更新的测试代码。

  it('should return a rejected promise', async() => {
    TestBed.resetTestingModule();
    TestBed.configureTestingModule({
      providers: [
        {
          provide: ObjectStore,
          useValue: new ObjectStore('test'),
        },
        {
          // Making this client invalid to trigger catch and throw error
          // I think writing a mock class to throw error also can be done
          // this is the "settings" from azure listConfigurationSettings 
          provide: AppConfigurationClient,
          useValue: {},
        }
      ]
    });
    service = TestBed.inject(FeatureFlagResolver);
    store = TestBed.inject(ObjectStore);
    const rejection = async () => {
      await service.resolve().catch();
    }
    await expect(rejection()).rejects.toThrow();
  });

“设置”是来自 MS azure 的 listConfigurationSettings。我们曾经从 azure 读取配置设置。 例如,我们想在 Angular 站点中启用某些东西,我们可以去 azure 门户更改应用程序设置(“聊天机器人”,“开”),这样聊天机器人就会出现在页面上。只是人们要打开、关闭的应用设置。

抱歉,我应该首先提供更多信息。

【问题讨论】:

  • 什么是settings
  • 在主线程中回复了上面

标签: javascript angular unit-testing jestjs karma-jasmine


【解决方案1】:

Never pass an async function as the executor to new Promise!您的功能应简化为

public async resolve(): Promise<{ [key: string]: boolean }> {
//     ^^^^^
  for await (const setting of settings) {
    // ObjectStore that acts like hashMap
    this.store.set(setting.key, setting.value);
  }
}

然后您将不需要对甚至不存在的代码路径进行单独测试。

此外,您可能不想使用for await,除非settings 是异步生成器。 鉴于更新的详细信息,it actually isPagedAsyncIterableIterator。但是,我建议不要将其存储在全局变量中,而是在完成 .listConfigurationSettings() 调用的同一函数中进行迭代。

【讨论】:

  • 您提供的链接中有一些读数。我会仔细阅读它们。了解更多信息是件好事。我公司有一位资深人士表示,该人不喜欢他们的代码被“修复”....但谢谢你让我更了解这种模式..
【解决方案2】:

您可以捕获错误并对其进行测试。类似于测试解析。

  describe('Test Case', () => {
    describe('Testing Sample 1', () => {
      it('should return a rejected promise', () => {
        service.resolve()
          .catch((error) => {
            expect(error).toEqual('the error string');
          });
      });
    });
  });

【讨论】:

  • 如果可行,您可以接受答案以供其他用户将来参考。
  • 您需要使用await expect(service.resolve()).rejects(),请参阅jestjs.io/docs/asynchronous。请注意,在上面的代码中,当 Promise 实现时,测试实际上确实成功了!
  • 谢谢@Bergi。虽然我使用了另一种方法,但我认为我们在这里完成了类似的事情。
猜你喜欢
  • 2018-10-10
  • 2018-10-29
  • 2013-02-08
  • 1970-01-01
  • 1970-01-01
  • 2018-03-03
  • 1970-01-01
  • 2019-09-28
  • 1970-01-01
相关资源
最近更新 更多