aboutsummaryrefslogtreecommitdiff
path: root/docs/test
diff options
context:
space:
mode:
Diffstat (limited to 'docs/test')
-rw-r--r--docs/test/lifecycle.md4
-rw-r--r--docs/test/mocks.md55
-rw-r--r--docs/test/time.md106
-rw-r--r--docs/test/writing.md92
4 files changed, 250 insertions, 7 deletions
diff --git a/docs/test/lifecycle.md b/docs/test/lifecycle.md
index ccb7ce85d..fd804c9bb 100644
--- a/docs/test/lifecycle.md
+++ b/docs/test/lifecycle.md
@@ -10,7 +10,7 @@ The test runner supports the following lifecycle hooks. This is useful for loadi
Perform per-test setup and teardown logic with `beforeEach` and `afterEach`.
```ts
-import { expect, test } from "bun:test";
+import { beforeEach, afterEach } from "bun:test";
beforeEach(() => {
console.log("running test.");
@@ -70,7 +70,7 @@ afterAll(() => {
Then use `--preload` to run the setup script before any test files.
```ts
-bun test --preload ./setup.ts
+$ bun test --preload ./setup.ts
```
To avoid typing `--preload` every time you run tests, it can be added to your `bunfig.toml`:
diff --git a/docs/test/mocks.md b/docs/test/mocks.md
new file mode 100644
index 000000000..31b5dab41
--- /dev/null
+++ b/docs/test/mocks.md
@@ -0,0 +1,55 @@
+Create mocks with the `mock` function.
+
+```ts
+import { test, expect, mock } from "bun:test";
+const random = mock(() => Math.random());
+
+test("random", async () => {
+ const val = random();
+ expect(val).toBeGreaterThan(0);
+ expect(random).toHaveBeenCalled();
+ expect(random).toHaveBeenCalledTimes(1);
+});
+```
+
+The result of `mock()` is a new function that's been decorated with some additional properties.
+
+```ts
+import { mock } from "bun:test";
+const random = mock((multiplier: number) => multiplier * Math.random());
+
+random(2);
+random(10);
+
+random.mock.calls;
+// [[ 2 ], [ 10 ]]
+
+random.mock.results;
+// [
+// { type: "return", value: 0.6533907460954099 },
+// { type: "return", value: 0.6452713933037312 }
+// ]
+```
+
+## `.spyOn()`
+
+It's possible to track calls to a function without replacing it with a mock. Use `spyOn()` to create a spy; these spies can be passed to `.toHaveBeenCalled()` and `.toHaveBeenCalledTimes()`.
+
+```ts
+import { test, expect, spyOn } from "bun:test";
+
+const ringo = {
+ name: "Ringo",
+ sayHi() {
+ console.log(`Hello I'm ${this.name}`);
+ },
+};
+
+const spy = spyOn(ringo, "sayHi");
+
+test("spyon", () => {
+ expect(spy).toHaveBeenCalledTimes(0);
+ ringo.sayHi();
+ expect(spy).toHaveBeenCalledTimes(1);
+});
+```
diff --git a/docs/test/time.md b/docs/test/time.md
new file mode 100644
index 000000000..4a0f98407
--- /dev/null
+++ b/docs/test/time.md
@@ -0,0 +1,106 @@
+`bun:test` lets you change what time it is in your tests. This was introduced in Bun v0.6.13.
+
+This works with any of the following:
+
+- `Date.now`
+- `new Date()`
+- `new Intl.DateTimeFormat().format()`
+
+Timers are not impacted yet, but may be in a future release of Bun.
+
+## `setSystemTime`
+
+To change the system time, use `setSystemTime`:
+
+```ts
+import { setSystemTime, beforeAll, test, expect } from "bun:test";
+
+beforeAll(() => {
+ setSystemTime(new Date("2020-01-01T00:00:00.000Z"));
+});
+
+test("it is 2020", () => {
+ expect(new Date().getFullYear()).toBe(2020);
+});
+```
+
+To support existing tests that use Jest's `useFakeTimers` and `useRealTimers`, you can use `useFakeTimers` and `useRealTimers`:
+
+```ts
+test("just like in jest", () => {
+ jest.useFakeTimers();
+ jest.setSystemTime(new Date("2020-01-01T00:00:00.000Z"));
+ expect(new Date().getFullYear()).toBe(2020);
+ jest.useRealTimers();
+ expect(new Date().getFullYear()).toBeGreaterThan(2020);
+});
+
+test("unlike in jest", () => {
+ const OriginalDate = Date;
+ jest.useFakeTimers();
+ if (typeof Bun === "undefined") {
+ // In Jest, the Date constructor changes
+ // That can cause all sorts of bugs because suddenly Date !== Date before the test.
+ expect(Date).not.toBe(OriginalDate);
+ expect(Date.now).not.toBe(OriginalDate.now);
+ } else {
+ // In bun:test, Date constructor does not change when you useFakeTimers
+ expect(Date).toBe(OriginalDate);
+ expect(Date.now).toBe(OriginalDate.now);
+ }
+});
+```
+
+{% callout %}
+**Timers** — Note that we have not implemented builtin support for mocking timers yet, but this is on the roadmap.
+{% /callout %}
+
+### Reset the system time
+
+To reset the system time, pass no arguments to `setSystemTime`:
+
+```ts
+import { setSystemTime, beforeAll } from "bun:test";
+
+test("it was 2020, for a moment.", () => {
+ // Set it to something!
+ setSystemTime(new Date("2020-01-01T00:00:00.000Z"));
+ expect(new Date().getFullYear()).toBe(2020);
+
+ // reset it!
+ setSystemTime();
+
+ expect(new Date().getFullYear()).toBeGreaterThan(2020);
+});
+```
+
+## Set the time zone
+
+To change the time zone, either pass the `$TZ` environment variable to `bun test`.
+
+```sh
+TZ=America/Los_Angeles bun test
+```
+
+Or set `process.env.TZ` at runtime:
+
+```ts
+import { test, expect } from "bun:test";
+
+test("Welcome to California!", () => {
+ process.env.TZ = "America/Los_Angeles";
+ expect(new Date().getTimezoneOffset()).toBe(420);
+ expect(new Intl.DateTimeFormat().resolvedOptions().timeZone).toBe(
+ "America/Los_Angeles",
+ );
+});
+
+test("Welcome to New York!", () => {
+ // Unlike in Jest, you can set the timezone multiple times at runtime and it will work.
+ process.env.TZ = "America/New_York";
+ expect(new Date().getTimezoneOffset()).toBe(240);
+ expect(new Intl.DateTimeFormat().resolvedOptions().timeZone).toBe(
+ "America/New_York",
+ );
+});
+```
diff --git a/docs/test/writing.md b/docs/test/writing.md
index 391ee91c2..6a29bf81f 100644
--- a/docs/test/writing.md
+++ b/docs/test/writing.md
@@ -63,6 +63,21 @@ test("2 * 2", done => {
});
```
+## Timeouts
+
+Optionally specify a per-test timeout in milliseconds by passing a number as the third argument to `test`.
+
+```ts
+import { test } from "bun:test";
+
+test.skip("wat", async () => {
+ const data = await slowOperation();
+ expect(data).toBe(42);
+}, 500); // test must run in <500ms
+```
+
+## `test.skip`
+
Skip individual tests with `test.skip`. These tests will not be run.
```ts
@@ -74,6 +89,8 @@ test.skip("wat", () => {
});
```
+## `test.todo`
+
Mark a test as a todo with `test.todo`. These tests _will_ be run, and the test runner will expect them to fail. If they pass, you will be prompted to mark it as a regular test.
```ts
@@ -84,6 +101,71 @@ test.todo("fix this", () => {
});
```
+To exlusively run tests marked as _todo_, use `bun test --todo`.
+
+```sh
+$ bun test --todo
+```
+
+## `test.only`
+
+To run a particular test or suite of tests use `test.only()` or `describe.only()`. Once declared, running `bun test --skip` will only execute tests/suites that have been marked with `.only()`.
+
+```ts
+import { test, describe } from "bun:test";
+
+test("test #1", () => {
+ // does not run
+});
+
+test.only("test #2", () => {
+ // runs
+});
+
+describe.only("only", () => {
+ test("test #3", () => {
+ // runs
+ });
+});
+```
+
+The following command will only execute tests #2 and #3.
+
+```sh
+$ bun test --only
+```
+
+## `test.if`
+
+To run a test conditionally, use `test.if()`. The test will run if the condition is truthy. This is particularly useful for tests that should only run on specific architectures or operating systems.
+
+```ts
+test.if(Math.random() > 0.5)("runs half the time", () => {
+ // ...
+});
+```
+
+```ts
+test.if(Math.random() > 0.5)("runs half the time", () => {
+ // ...
+});
+
+const macOS = process.arch === "darwin";
+test.if(macOS)("runs on macOS", () => {
+ // runs if macOS
+});
+```
+
+To instead skip a test based on some condition, use `test.skipIf()` or `describe.skipIf()`.
+
+```ts
+const macOS = process.arch === "darwin";
+
+test.skipIf(macOS)("runs on non-macOS", () => {
+ // runs if *not* macOS
+});
+```
+
## Matchers
Bun implements the following matchers. Full Jest compatibility is on the roadmap; track progress [here](https://github.com/oven-sh/bun/issues/1825).
@@ -217,13 +299,13 @@ Bun implements the following matchers. Full Jest compatibility is on the roadmap
---
-- 🔴
-- [`.resolves()`](https://jestjs.io/docs/expect#resolves)
+- 🟢
+- [`.resolves()`](https://jestjs.io/docs/expect#resolves) (since Bun v0.6.12+)
---
-- 🔴
-- [`.rejects()`](https://jestjs.io/docs/expect#rejects)
+- 🟢
+- [`.rejects()`](https://jestjs.io/docs/expect#rejects) (since Bun v0.6.12+)
---
@@ -277,7 +359,7 @@ Bun implements the following matchers. Full Jest compatibility is on the roadmap
---
-- 🔴
+- 🟢
- [`.toBeCloseTo()`](https://jestjs.io/docs/expect#tobeclosetonumber-numdigits)
---