UNPKG

6.26 kBMarkdownView Raw
1[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)
2[![CircleCI](https://circleci.com/gh/TheBrainFamily/wait-for-expect.svg?style=shield)](https://circleci.com/gh/TheBrainFamily/wait-for-expect)
3
4# wait-for-expect
5Wait for expectation to be true, useful for integration and end to end testing
6
7Think things like calling external APIs, database operations, or even GraphQL subscriptions.
8We will add examples for all of them soon, for now please enjoy the simple docs. :-)
9
10# Usage:
11
12```javascript
13const waitForExpect = require("wait-for-expect")
14
15test("it waits for the number to change", async () => {
16 let numberToChange = 10;
17 // we are using random timeout here to simulate a real-time example
18 // of an async operation calling a callback at a non-deterministic time
19 const randomTimeout = Math.floor(Math.random() * 300);
20
21 setTimeout(() => {
22 numberToChange = 100;
23 }, randomTimeout);
24
25 await waitForExpect(() => {
26 expect(numberToChange).toEqual(100);
27 });
28});
29```
30
31instead of:
32
33```javascript
34
35test("it waits for the number to change", () => {
36 let numberToChange = 10;
37 const randomTimeout = Math.floor(Math.random() * 300);
38
39 setTimeout(() => {
40 numberToChange = 100;
41 }, randomTimeout);
42
43 setTimeout(() => {
44 expect(numberToChange).toEqual(100);
45 }, 700);
46});
47```
48
49It will check whether the expectation passes right away in the next available "tick" (very useful with, for example, integration testing of react when mocking fetches, like here: https://github.com/kentcdodds/react-testing-library#usage).
50
51If it doesn't, it will keep repeating for the duration of, at most, the specified timeout, every 50 ms. The default timeout is 4.5 seconds to fit below the default 5 seconds that Jest waits for before throwing an error.
52
53Nice thing about this simple tool is that if the expectation keeps failing till the timeout, it will check it one last time, but this time the same way your test runner would run it - so you basically get your expectation library error, the sam way like if you used setTimeout to wait but didn't wait long enough.
54
55To show an example - if I change the expectation to wait for 105 in above code, you will get nice and familiar:
56
57```
58
59 FAIL src/waitForExpect.spec.js (5.042s)
60 ✕ it waits for the number to change (4511ms)
61
62 ● it waits for the number to change
63
64 expect(received).toEqual(expected)
65
66 Expected value to equal:
67 105
68 Received:
69 100
70
71 9 | }, 600);
72 10 | await waitForExpect(() => {
73 > 11 | expect(numberToChange).toEqual(105);
74 12 | });
75 13 | });
76 14 |
77
78 at waitForExpect (src/waitForExpect.spec.js:11:28)
79 at waitUntil.catch (src/index.js:61:5)
80
81Test Suites: 1 failed, 1 total
82Tests: 1 failed, 1 total
83Snapshots: 0 total
84Time: 5.807s
85```
86
87You can add multiple expectations to wait for, all of them have to pass, and if one of them don't, it will be marked.
88For example, let's add another expectation for a different number, notice how jest tells you that that's the expectation that failed.
89
90```
91 expect(received).toEqual(expected)
92
93 Expected value to equal:
94 110
95 Received:
96 105
97
98 11 | await waitForExpect(() => {
99 12 | expect(numberToChange).toEqual(100);
100 > 13 | expect(numberThatWontChange).toEqual(110);
101 14 | });
102 15 | });
103 16 |
104
105 at waitForExpect (src/waitForExpect.spec.js:13:34)
106 at waitUntil.catch (src/index.js:61:5)
107```
108
109Since 0.6.0 we can now work with promises, for example, this is now possible:
110
111```javascript
112test("rename todo by typing", async () => {
113 // (..)
114 const todoToChange = getTodoByText("original todo");
115 todoToChange.value = "different text now";
116 Simulate.change(todoToChange);
117
118 await waitForExpect(() =>
119 expect(
120 todoItemsCollection.findOne({
121 text: "different text now"
122 })).resolves.not.toBeNull()
123 );
124});
125```
126
127Async Await also works, as in this example - straight from our test case
128
129```javascript
130test("it works with promises", async () => {
131 let numberToChange = 10;
132 const randomTimeout = Math.floor(Math.random() * 300);
133
134 setTimeout(() => {
135 numberToChange = 100;
136 }, randomTimeout);
137
138 const sleep = (ms) =>
139 new Promise(resolve => setTimeout(() => resolve(), ms));
140
141 await waitForExpect(async () => {
142 await sleep(10);
143 expect(numberToChange).toEqual(100);
144 });
145});
146```
147
148(Note: Obviously, in this case it doesn't make sense to put the await sleep there, this is just for demonstration purpose)
149
150# API
151waitForExpect takes 3 arguments, 2 optional.
152
153```javascript
154/**
155 * Waits for predicate to not throw and returns a Promise
156 *
157 * @param expectation Function Predicate that has to complete without throwing
158 * @param timeout Number Maximum wait interval, 4500ms by default
159 * @param interval Number Wait interval, 50ms by default
160 * @return Promise Promise to return a callback result
161 */
162```
163
164The defaults for `timeout` and `interval` can also be edited globally, e.g. in a jest setup file:
165```javascript
166import waitForExpect from 'wait-for-expect';
167
168waitForExpect.defaults.timeout = 2000;
169waitForExpect.defaults.interval = 10;
170```
171
172## Changelog
1731.0.0 - 15 June 2018
174
175( For most people this change doesn't matter. )
176Export the function directly in module.exports instead of exporting as an object that has default key. If that's not clear (...it isn't ;-) ) - check #8 #9 .
177Thanks to @mbaranovski for the PR and @BenBrostoff for creating the issue! I'm making this 1.0.0 as this is breaking for people that currently did:
178```javascript
179const { default: waitFor } = require('wait-for-expect');
180```
181
1820.6.0 - 3 May 2018
183
184Work with promises.
185
1860.5.0 - 10 April 2018
187
188Play nicely with jest fake timers (and also in any test tool that overwrites setTimeout) - thanks to @slightlytyler and @kentcoddods for helping to get this resolved.
189
190## Credit
191Originally based on ideas from https://github.com/devlato/waitUntil.
192Simplified highly and rewritten for 0.1.0 version.
193Simplified even more and rewritten even more for 0.2.0 with guidance from Kent C. Dodds: https://github.com/kentcdodds/react-testing-library/pull/25
\No newline at end of file