Skip to content

Commit b065452

Browse files
committed
03/04: add solution text
1 parent 1609a18 commit b065452

File tree

1 file changed

+33
-14
lines changed
  • exercises/03.assertions/04.solution.retryable-assertions

1 file changed

+33
-14
lines changed

exercises/03.assertions/04.solution.retryable-assertions/README.mdx

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
# Retryable assertions
22

3-
- Use `expect.poll` to retry any assertion.
4-
- Use `expect.element()` in the Browser Mode for built-in polling + element-based assertions.
5-
6-
---
7-
83
I will start from removing the `vi.waitFor()` block I have in the test:
94

105
```ts filename=src/client.test.ts remove=8-10
@@ -47,25 +42,49 @@ Similar to `vi.waitFor()`, the `expect.poll()` call _returns a Promise_ that you
4742

4843
You might be wondering: How is this different from `vi.waitFor()`?
4944

50-
...
45+
On the surface, two approaches simply differ syntactically, but there's more to it. `vi.waitFor()` isn't really meant to be used with assertions. The way assertion errors are nested in the callback make it somewhat harder for Vitest to process them. `expect.poll()`, on the other hand, is tailored exclusively for eventual assertions.
46+
47+
This makes the distinction between the two APIs a bit more clear.
5148

52-
- [ ] Explain the difference between `vi.waitFor()` and `expect.poll()` and when you'd want to use each.
49+
| `vi.waitFor()` | `expect.poll()` |
50+
| ----------------------------------------------------------------------------------------------------------- | ---------------------------------------- |
51+
| Use to wait for a side effect or a state transition not directly related to the expectation you're testing. | Use to describe an eventual expectation. |
52+
53+
<callout-success>In Vitest Browser Mode, `expect.element()` is built around `expect.poll()` so you don't need to poll for values manually. When testing your components, prefer `expect.element()` instead.</callout-success>
54+
55+
Here's how you would apply each API:
5356

5457
```ts
55-
await vi.waitFor(() => {
56-
expect(fn).toHaveBeenCalled()
58+
// Let's say this `action` is your starting interaction with the system.
59+
// (i.e. it begins the state transition)
60+
await action()
61+
62+
// Wait for certain side effects to complete.
63+
// These are not related to what you're testing but are rather
64+
// required before you proceed with your test.
65+
await vi.waitFor(async () => {
66+
// You can still use `expect()` here as a shorthand for resolving
67+
// when a condition is met and rejecting when it's not. You can also
68+
// use things like `invariant` or throwing errors manually.
69+
await sideEffect()
5770
})
5871

59-
// is the same as this:
72+
// Now that the system is in the correct next state,
73+
// continue interacting with it as the user would.
74+
await anotherAction()
6075

61-
await expect.poll(() => fn).toHaveBeenCalled()
76+
// Finally, write assertions that reflect your expectations.
77+
// In this case, an eventual expectation for the `state` to
78+
// become `expected`.
79+
await expect.poll(state).toBe(expected)
6280
```
6381

6482
## Limitations of `expect.poll()`
6583

66-
- `expect.poll()` doesn't work with all matchers (no support for snapshot matchers, e.g.);
67-
- `expect.poll()` always awaits the given promise, which means there's no `.rejects` or `.resolves`;
68-
- `expect.poll()` won't work with `.toThrow()` so don't use it for negative assertions.
84+
That being said, `expect.poll()` comes with a few limitations that you have to keep in mind when using it.
85+
86+
1. It doesn't work with all matchers (e.g. doesn't support snapshot matchers);
87+
1. The Promise it returns _can only resolve_, which means there's no `.rejects.` or `.resolves.` chaining after `expect.poll()`. For example, you cannot use it with `.toThrow(error)` for negative assertions.
6988

7089
## Related materials
7190

0 commit comments

Comments
 (0)