@@ -263,24 +263,32 @@ function Login() {
263
263
}
264
264
265
265
export default Login
266
+ ```
266
267
268
+ ```jsx
267
269
// __tests__/login.js
268
270
// again, these first two imports are something you' d normally handle in
269
271
// your testing framework configuration rather than importing them in every file.
270
272
import ' @testing-library/jest-dom'
271
273
import React from ' react'
274
+ // import API mocking utilities from Mock Service Worker.
275
+ import {rest } from ' msw'
276
+ import {setupServer } from ' msw/node'
277
+ // import testing utilities
272
278
import {render , fireEvent , screen } from ' @testing-library/react'
273
279
import Login from ' ../login'
274
280
275
- test (' allows the user to login successfully' , async () => {
276
- // mock out window.fetch for the test
277
- const fakeUserResponse = {token: ' fake_user_token' }
278
- jest .spyOn (window , ' fetch' ).mockImplementationOnce (() => {
279
- return Promise .resolve ({
280
- json : () => Promise .resolve (fakeUserResponse),
281
- })
281
+ const server = setupServer (
282
+ rest .post (' /api/login' , (req , res , ctx ) => {
283
+ return res (ctx .json ({token: ' fake_user_token' }))
282
284
})
285
+ )
283
286
287
+ beforeAll (() => server .listen ())
288
+ afterEach (() => server .resetHandlers ())
289
+ afterAll (() => server .close ())
290
+
291
+ test (' allows the user to login successfully' , async () => {
284
292
render (< Login / > )
285
293
286
294
// fill out the form
@@ -303,8 +311,42 @@ test('allows the user to login successfully', async () => {
303
311
expect (alert).toHaveTextContent (/ congrats/ i )
304
312
expect (window .localStorage .getItem (' token' )).toEqual (fakeUserResponse .token )
305
313
})
314
+
315
+ test (' handles server exceptions' , async () => {
316
+ // mock the server error response for this test suite only.
317
+ server .use (
318
+ rest .post (' /' , (req , res , ctx ) => {
319
+ return res (
320
+ ctx .status (500 ),
321
+ ctx .json ({message: ' Internal server error' }),
322
+ )
323
+ })
324
+ )
325
+
326
+ render (< Login / > )
327
+
328
+ // fill out the form
329
+ fireEvent .change (screen .getByLabelText (/ username/ i ), {
330
+ target: {value: ' chuck' },
331
+ })
332
+ fireEvent .change (screen .getByLabelText (/ password/ i ), {
333
+ target: {value: ' norris' },
334
+ })
335
+
336
+ fireEvent .click (screen .getByText (/ submit/ i ))
337
+
338
+ // wait for the error message
339
+ const alert = await screen .findByRole (' alert' )
340
+
341
+ expect (alert).toHaveTextContent (/ internal server error/ i )
342
+ expect (window .localStorage .getItem (' token' )).toBeNull ()
343
+ })
306
344
` ` `
307
345
346
+ > We recommend using [Mock Service Worker](https://github.com/mswjs/msw) library
347
+ > to declaratively mock API communication in your tests instead of stubbing
348
+ > ` window .fetch ` , or relying on third-party adapters.
349
+
308
350
### More Examples
309
351
310
352
> We're in the process of moving examples to the
0 commit comments