Skip to content

Commit

Permalink
upgrade react-testing-library and use wait instead. Much improved
Browse files Browse the repository at this point in the history
  • Loading branch information
Kent C. Dodds committed Mar 30, 2018
1 parent 680c9ae commit 87b967a
Show file tree
Hide file tree
Showing 10 changed files with 62 additions and 51 deletions.
3 changes: 1 addition & 2 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@
"devDependencies": {
"jest-glamor-react": "^4.2.0",
"react-scripts": "^2.0.0-next.47d2d941",
"react-test-renderer": "^16.2.0",
"react-testing-library": "^1.6.0",
"react-testing-library": "^1.9.1",
"til-shared": "file:../shared"
},
"browserslist": {
Expand Down
17 changes: 11 additions & 6 deletions client/src/__tests__/app.create-post.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import React from 'react'
import {Simulate} from 'react-dom/test-utils'
import axiosMock from 'axios'
import {renderWithRouter, flushPromises, generate} from 'client-test-utils'
import {renderWithRouter, generate} from 'client-test-utils'
import {init as initAPI} from '../utils/api'
import App from '../app'

Expand Down Expand Up @@ -42,10 +42,15 @@ test('create post', async () => {
}
})

const {container, getByText, getByLabelText} = renderWithRouter(<App />)
const {
container,
getByText,
getByLabelText,
finishLoading,
} = renderWithRouter(<App />)

// wait for /me request to settle
await flushPromises()
// wait for the app to finish loading the mocked requests
await finishLoading()
axiosMock.__mock.reset()

// navigate to register
Expand Down Expand Up @@ -86,8 +91,8 @@ test('create post', async () => {
date: expect.any(String),
})

// wait for promises to settle
await flushPromises()
// wait for the mocked requests to finish
await finishLoading()

expect(window.location.href).not.toContain('editor')

Expand Down
25 changes: 12 additions & 13 deletions client/src/__tests__/app.login.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,7 @@

import React from 'react'
import axiosMock from 'axios'
import {
renderWithRouter,
flushPromises,
generate,
Simulate,
} from 'client-test-utils'
import {renderWithRouter, generate, Simulate} from 'client-test-utils'
import {init as initAPI} from '../utils/api'
import App from '../app'

Expand All @@ -24,12 +19,16 @@ beforeEach(() => {
})

test('login as an existing user', async () => {
const {getByTestId, container, getByText, getByLabelText} = renderWithRouter(
<App />,
)
const {
getByTestId,
container,
getByText,
getByLabelText,
finishLoading,
} = renderWithRouter(<App />)

// wait for /me request to settle
await flushPromises()
// wait for the app to finish loading the mocked requests
await finishLoading()

// navigate to login
const leftClick = {button: 0}
Expand All @@ -54,8 +53,8 @@ test('login as an existing user', async () => {
)
Simulate.submit(formWrapper)

// wait for promises to settle
await flushPromises()
// wait for the mocked requests to finish
await finishLoading()

// assert calls
expect(axiosMock.__mock.instance.post).toHaveBeenCalledTimes(1)
Expand Down
4 changes: 2 additions & 2 deletions client/src/__tests__/app.login.todo.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
test('login as an existing user', async () => {
// render the app with the router provider and custom history
//
// wait for /me request to settle
// wait for the app to finish loading the mocked requests
//
// navigate to login by clicking login-link
//
Expand All @@ -16,7 +16,7 @@ test('login as an existing user', async () => {
// which you can generate with generate.token(fakeUser)
// Now simulate a submit event on the form
//
// wait for promises to settle
// wait for the mocked requests to finish
//
// assert post was called correctly
// assert localStorage is correct
Expand Down
20 changes: 12 additions & 8 deletions client/src/__tests__/app.register.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import React from 'react'
import {Simulate} from 'react-dom/test-utils'
import axiosMock from 'axios'
import {renderWithRouter, flushPromises, generate} from 'client-test-utils'
import {renderWithRouter, generate} from 'client-test-utils'
import {init as initAPI} from '../utils/api'
import App from '../app'

Expand All @@ -20,12 +20,16 @@ beforeEach(() => {
})

test('register a new user', async () => {
const {container, getByTestId, getByText, getByLabelText} = renderWithRouter(
<App />,
)
const {
container,
getByTestId,
getByText,
finishLoading,
getByLabelText,
} = renderWithRouter(<App />)

// wait for /me request to settle
await flushPromises()
// wait for the app to finish loading the mocked requests
await finishLoading()

// navigate to register
const leftClick = {button: 0}
Expand All @@ -50,8 +54,8 @@ test('register a new user', async () => {
)
Simulate.submit(formWrapper)

// wait for promises to settle
await flushPromises()
// wait for the mocked requests to finish
await finishLoading()

// assert calls
expect(axiosMock.__mock.instance.post).toHaveBeenCalledTimes(1)
Expand Down
4 changes: 2 additions & 2 deletions client/src/__tests__/app.register.todo.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
test('register a new user', async () => {
// render the app with the router provider and custom history
//
// wait for /me request to settle
// wait for the app to finish loading the mocked requests
//
// navigate to register by clicking register-link
//
Expand All @@ -17,7 +17,7 @@ test('register a new user', async () => {
// which you can generate with generate.token(fakeUser)
// Now simulate a submit event on the form
//
// wait for promises to settle
// wait for the mocked requests to finish
//
// assert post was called correctly
// assert localStorage is correct
Expand Down
8 changes: 4 additions & 4 deletions client/src/__tests__/app.snapshot.not-recommended.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import React from 'react'
import axiosMock from 'axios'
import {renderWithRouter, flushPromises, generate} from 'client-test-utils'
import {renderWithRouter} from 'client-test-utils'
import {init as initAPI} from '../utils/api'
import App from '../app'

Expand Down Expand Up @@ -41,9 +41,9 @@ test('snapshot', async () => {
}
})

const {container} = renderWithRouter(<App />)
const {container, finishLoading} = renderWithRouter(<App />)

// wait for /me request to settle
await flushPromises()
// wait for the app to finish loading the mocked requests
await finishLoading()
expect(container.firstChild).toMatchSnapshot()
})
16 changes: 8 additions & 8 deletions client/src/components/__tests__/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import React from 'react'
import ReactDOM from 'react-dom'
import {flushPromises, generate} from 'client-test-utils'
import {wait, generate} from 'client-test-utils'
import User from '../user'
import * as apiMock from '../../utils/api'

Expand Down Expand Up @@ -48,10 +48,11 @@ test('login rerenders with the retrieved user', async () => {
)
const form = generate.loginForm(fakeUser)
controller.login(form)
await flushPromises()
expect(apiMock.auth.login).toHaveBeenCalledTimes(1)
expect(apiMock.auth.login).toHaveBeenCalledWith(form)
expect(children).toHaveBeenCalledTimes(2)

await wait(() => expect(children).toHaveBeenCalledTimes(2))

expect(children).toHaveBeenCalledWith(
expect.objectContaining({
pending: true,
Expand All @@ -71,9 +72,8 @@ test('login rerenders with the retrieved user', async () => {
test('logout rerenders with a null user', async () => {
const {children, controller} = await setup()
controller.logout()
await flushPromises()
expect(apiMock.auth.logout).toHaveBeenCalledTimes(1)
expect(children).toHaveBeenCalledTimes(2)
await wait(() => expect(children).toHaveBeenCalledTimes(2))
expect(children).toHaveBeenCalledWith(
expect.objectContaining({
pending: true,
Expand All @@ -99,10 +99,9 @@ test('on register failure, rerenders with the error', async () => {
const form = generate.loginForm()
// the catch below is simply to ignore the error thrown
controller.register(form).catch(i => i)
await flushPromises()
expect(apiMock.auth.register).toHaveBeenCalledTimes(1)
expect(apiMock.auth.register).toHaveBeenCalledWith(form)
expect(children).toHaveBeenCalledTimes(2)
await wait(() => expect(children).toHaveBeenCalledTimes(2))
expect(children).toHaveBeenCalledWith(
expect.objectContaining({
pending: true,
Expand All @@ -127,7 +126,8 @@ async function setup() {
})
const div = document.createElement('div')
ReactDOM.render(<User>{children}</User>, div)
await flushPromises()
children.mockClear()
await wait(() => expect(children).toHaveBeenCalledTimes(1))
children.mockClear()
return {controller, children}
}
9 changes: 5 additions & 4 deletions client/src/screens/__tests__/editor.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react'
import {generate, render, Simulate, flushPromises} from 'client-test-utils'
import {generate, render, Simulate, wait} from 'client-test-utils'
import Editor from '../editor'

test('calls onSubmit with the username and password when submitted', async () => {
Expand All @@ -26,15 +26,16 @@ test('calls onSubmit with the username and password when submitted', async () =>
// Act
Simulate.submit(formNode)

const postDate = Date.now()
await flushPromises()

// Assert
expect(fakeApi.posts.create).toHaveBeenCalledTimes(1)
expect(fakeApi.posts.create).toHaveBeenCalledWith({
...fakePost,
date: expect.any(String),
})

const postDate = Date.now()
await wait(() => expect(fakeHistory.push).toHaveBeenCalledTimes(1))
expect(fakeHistory.push).toHaveBeenCalledWith('/')
const date = new Date(fakeApi.posts.create.mock.calls[0][0].date).getTime()
expect(date).toBeGreaterThanOrEqual(preDate)
expect(date).toBeLessThanOrEqual(postDate)
Expand Down
7 changes: 5 additions & 2 deletions client/test/client-test-utils.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import React from 'react'
import {Router} from 'react-router-dom'
import {render, flushPromises, Simulate} from 'react-testing-library'
import {render, wait, Simulate} from 'react-testing-library'
import {createMemoryHistory} from 'history'
import * as generate from 'til-shared/generate'

function renderWithRouter(ui, {route = '/', ...renderOptions} = {}) {
const history = createMemoryHistory({initialEntries: [route]})
const utils = render(<Router history={history}>{ui}</Router>, renderOptions)
const finishLoading = () =>
wait(() => expect(utils.queryByText('Loading')).toBeNull())
return {
...utils,
finishLoading,
history,
}
}

export {renderWithRouter, generate, render, flushPromises, Simulate}
export {renderWithRouter, generate, render, wait, Simulate}

0 comments on commit 87b967a

Please sign in to comment.