typescript 如何测试一个void异步函数在jest中是否成功?

mdfafbf1  于 2022-12-14  发布在  TypeScript
关注(0)|答案(4)|浏览(209)

如何用jest简洁地测试void异步函数是否成功执行?

// foo.ts
export class Foo {
  public async bar(): Promise<void> {
    await someAsync();
  }
}

如何测试new Foo().bar()不抛出错误?

iklwldmw

iklwldmw1#

这是我发现的语义最丰富的方法,甚至只是测试名称的翻译。

describe("Foo.bar()", () => {
      test("Should not throw", async () => {
        await expect(new Foo().bar()).resolves.not.toThrow();
      });
    });
kcwpcxri

kcwpcxri2#

Promise的优点是它根本不应该抛出,而是被解析或拒绝。另一方面,toBe()Assert需要一个参数,即使TypeScript中有一个Promise<void>
那么,如果没有传递参数(或者参数为空),但仍然对它求值,那么参数就是undefined

test("Should resolve", async () => {
      await expect(new Foo().bar()).resolves.toBeUndefined();
  });

not.toThrow()的测试碰巧对我来说是一个虚假的朋友,因为我的Foo.bar()没有抛出,也没有解决。

xdyibdwo

xdyibdwo3#

这是我找到的最好的方式。希望有更优雅的方式。

describe("Foo.bar()", () => {
  it("should not throw", async () => {
    expect.assertions(1);

    try {
      await new Foo().bar();
      expect(true).toBeTruthy();
    } catch {
      // should not come here
    }
  });
});
rsl1atfo

rsl1atfo4#

......备选项是resolvesAssert。

describe("Foo.bar()", () => {
  it("should not throw", () => {
      return expect(new Foo().bar()).resolves.toEqual();
  });
});

在这里你必须返回result,因为它是一个Promise(并且让jest等待它被实现)。如果你只需要验证resolved(或者rejected --有类似的prop rejects用于检查reject值),它会稍微简洁一些。
但是,如果您需要在运行基于承诺的函数后运行几项检查,如

describe("Foo.bar()", () => {
  it("should not throw", () => {
      const promise = new Foo().bar()
      expect(promise).resolves.toEqual();
      expect(someMock).toHaveBeenCalled();
      return promise;
  });
});

您可能会发现async/await选项更...令人满意?
附言,对于你的变体

describe("Foo.bar()", () => {
  it("should not throw", async () => {
    expect.assertions(1);

    try {
      await new Foo().bar();
      expect(true).toBeTruthy();
    } catch {
      // should not come here
    }
  });
});

我相信它不需要捕获错误-所以expect.assertions也变得多余。为什么?未捕获的异常将使您的测试失败,它不期望任何异常,所以使它失败是可以的。如果您期望异常并希望检查其属性,则需要这样的结构。
此外,如果测试失败,expect.assertions选项将通知您它失败了,而未捕获的异常将突出显示特定语句(如果测试有几个可能的异常语句,则非常有用)
[UPD]我也错过了最初的一点,你需要检查是否承诺是解决 * 任何 * 结果(我的版本检查它解决了undefined,这是不是真的很好的举动(它不会破坏任何东西,如果函数开始返回 * 东西 *,如果它返回 * 没有 * 之前)。同时,我们应该有至少一个检查在测试...
因此,也许您使用存根expect(true)的方法在这里也是合法的。
但是,如果您不想在同一个测试用例中生成更多的expect,我会验证两次。测试中的语句真的是如此孤立吗?或者您只是将相关的检查分解到单独的it()中?

相关问题