Skip to content

Commit 28489af

Browse files
authored
Merge pull request #3876 from nickmccurdy/writing-tests-hooks
Simplify Writing Tests recipe with hooks
2 parents 5430433 + 841fe44 commit 28489af

File tree

1 file changed

+7
-83
lines changed

1 file changed

+7
-83
lines changed

docs/recipes/WritingTests.md

Lines changed: 7 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -256,9 +256,7 @@ describe('todos reducer', () => {
256256

257257
### Components
258258

259-
A nice thing about React components is that they are usually small and only rely on their props. That makes them easy to test.
260-
261-
First, we will install [React Testing Library](https://testing-library.com/docs/react-testing-library/intro). React Testing Library is a simple and complete React DOM testing utilities that encourage good testing practices. It uses react-dom's `render` function and `act` from react-dom/tests-utils.
259+
First, we will install [React Testing Library](https://testing-library.com/docs/react-testing-library/intro). React Testing Library is a simple and complete React DOM testing utility that encourage good testing practices. It uses react-dom's `render` function and `act` from react-dom/tests-utils.
262260

263261
```sh
264262
npm install --save-dev @testing-library/react
@@ -270,92 +268,18 @@ If you are using jest as recommended above, we also recommend installing [jest-d
270268
npm install --save-dev @testing-library/jest-dom
271269
```
272270

273-
To test the components, we `render` them into the DOM and pass stubbed callbacks as props, then we assert whether the callbacks were called when expected.
274-
275-
#### Example
276-
277-
```js
278-
import React from 'react'
279-
import PropTypes from 'prop-types'
280-
import TodoTextInput from './TodoTextInput'
281-
282-
const Header = ({ addTodo }) => {
283-
const handleSave = text => {
284-
if (text.length !== 0) {
285-
addTodo(text)
286-
}
287-
}
288-
289-
return (
290-
<header className="header">
291-
<h1>todos</h1>
292-
<TodoTextInput
293-
newTodo={true}
294-
onSave={handleSave}
295-
placeholder="What needs to be done?"
296-
/>
297-
</header>
298-
)
299-
}
300-
301-
Header.propTypes = {
302-
addTodo: PropTypes.func.isRequired
303-
}
304-
305-
export default Header
306-
```
307-
308-
can be tested like:
309-
310-
```js
311-
import React from 'react'
312-
import { render, fireEvent, screen } from '@testing-library/react'
313-
import Header from '../../components/Header'
314-
315-
it('should not call addTodo if length of text is 0', () => {
316-
const mockAddTodo = jest.fn()
317-
render(<Header addTodo={mockAddTodo} />)
318-
319-
fireEvent.change(screen.getByPlaceholderText(/what needs to be done/i), {
320-
target: { value: '' }
321-
})
322-
323-
expect(mockAddTodo).toHaveBeenCalledTimes(0)
324-
})
325-
326-
it('should call addTodo if length of text is greater than 0', () => {
327-
const mockAddTodo = jest.fn()
328-
render(<Header addTodo={mockAddTodo} />)
329-
330-
fireEvent.change(screen.getByPlaceholderText(/what needs to be done/i), {
331-
target: { value: 'Use Redux' }
332-
})
333-
334-
expect(mockAddTodo).toHaveBeenCalledTimes(1)
335-
})
336-
```
337-
338-
### Connected Components
339-
340-
If you use a library like [React Redux](https://github.com/reduxjs/react-redux), you might be using [higher-order components](https://medium.com/@dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750) like [`connect()`](https://react-redux.js.org/api/connect). This lets you inject Redux state into a regular React component.
341-
342271
Consider the following `App` component:
343272

344273
```js
345-
import { connect } from 'react-redux'
346-
347-
const App = props => {
348-
return <div>{props.user}</div>
349-
}
274+
import { useSelector } from 'react-redux'
350275

351-
const mapStateToProps = state => {
352-
return state
276+
export default function App() {
277+
const user = useSelector(state => state.user)
278+
return <div>{user}</div>
353279
}
354-
355-
export default connect(mapStateToProps)(App)
356280
```
357281

358-
To test it, we can use the `wrapper` option in React Testing Library's `render` function and export our own `render` function as explained in React Testing Library's [setup docs](https://testing-library.com/docs/react-testing-library/setup).
282+
To test the component, we `render` it into the DOM and pass stubbed callbacks as props, then we assert whether the callbacks were called when expected. We can use the `wrapper` option in the `render` function and export our own `render` function as explained in React Testing Library's [setup docs](https://testing-library.com/docs/react-testing-library/setup).
359283

360284
Our `render` function can look like this:
361285

@@ -398,7 +322,7 @@ import React from 'react'
398322
import { render, fireEvent, screen } from '../../test-utils'
399323
import App from '../../containers/App'
400324

401-
it('Renders the connected app with initialState', () => {
325+
it('Renders the app with initialState', () => {
402326
render(<App />, { initialState: { user: 'Redux User' } })
403327

404328
expect(screen.getByText(/redux user/i)).toBeInTheDocument()

0 commit comments

Comments
 (0)