bun:test/valid-expect-in-promise

Require a promise chain that contains expect to be awaited or returned from the test

error by default

A callback passed to .then(), .catch() or .finally() runs later. If the test doesn't await or return the promise, bun test doesn't wait for it. The test is over before the expect in the callback runs, so a failed assertion doesn't fail that test.

This rule is on by default in files that import from "bun:test".

Configure#

On by default as an error. To turn it off:

bunfig.toml
[lint.rules]
"bun:test/valid-expect-in-promise" = "off" # or "warn"

Examples#

example.ts1 problem
import { expect, test } from "bun:test";

test("loads the user", () => {
  loadUser(1).then((user) => {
    expect(user.name).toBe("Ada");
  });
});

A promise kept in a variable must be awaited or returned too:

example.ts1 problem
import { expect, test } from "bun:test";

test("loads the user", () => {
  const check = loadUser(1).then((user) => {
    expect(user.name).toBe("Ada");
  });
});

Code after the test's return never runs:

example.ts1 problem
import { expect, test } from "bun:test";

test("loads both users", () => {
  return loadUser(1).then((user) => {
    expect(user.name).toBe("Ada");
  });
  loadUser(2).then((user) => {
    expect(user.name).toBe("Grace");
  });
});
example.tsNo problems
import { expect, test } from "bun:test";

test("loads the user", () => {
  return loadUser(1).then((user) => {
    expect(user.name).toBe("Ada");
  });
});

test("loads the admin", async () => {
  await loadUser(2).then((user) => {
    expect(user.role).toBe("admin");
  });
});

test("loads the guest", async () => {
  const user = await loadUser(3);
  expect(user.role).toBe("guest");
});

Several promises can be awaited together:

example.tsNo problems
import { expect, test } from "bun:test";

test("loads both users", async () => {
  const first = loadUser(1).then((user) => {
    expect(user.name).toBe("Ada");
  });
  const second = loadUser(2).then((user) => {
    expect(user.name).toBe("Grace");
  });
  await Promise.all([first, second]);
});

A test with a parameter isn't checked, because calling done is another way to make bun test wait:

example.tsNo problems
import { expect, test } from "bun:test";

test("loads the user", (done) => {
  loadUser(1).then((user) => {
    expect(user.name).toBe("Ada");
    done();
  });
});