Skip to content

Commit 9c606da

Browse files
AndrewmatKent C. Dodds
authored and
Kent C. Dodds
committed
feat(testHook): modify testHook to return unmount function (#290)
* Returns unmount function on testHook * Adds test for unmount function; Adds example of useEffect * Add Andrewmat as contributor * Adds rerender on testHook return
1 parent ac58967 commit 9c606da

File tree

8 files changed

+164
-43
lines changed

8 files changed

+164
-43
lines changed

.all-contributorsrc

+11
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,17 @@
657657
"bug",
658658
"code"
659659
]
660+
},
661+
{
662+
"login": "Andrewmat",
663+
"name": "André Matulionis dos Santos",
664+
"avatar_url": "https://avatars0.githubusercontent.com/u/5133846?v=4",
665+
"profile": "https://twitter.com/Andrewmat",
666+
"contributions": [
667+
"code",
668+
"example",
669+
"test"
670+
]
660671
}
661672
]
662673
}

.github/ISSUE_TEMPLATE.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ What happened:
5959

6060
<!-- Please provide the full error message/screenshots/anything -->
6161

62-
Reproduction repository: https://github.com/alexkrolick/dom-testing-library-template
62+
Reproduction repository:
63+
https://github.com/alexkrolick/dom-testing-library-template
6364

6465
<!--
6566
If possible, please create a repository that reproduces the issue with the

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ practices.</p>
2626
[![version][version-badge]][package] [![downloads][downloads-badge]][npmtrends]
2727
[![MIT License][license-badge]][license]
2828

29-
[![All Contributors](https://img.shields.io/badge/all_contributors-67-orange.svg?style=flat-square)](#contributors)
29+
[![All Contributors](https://img.shields.io/badge/all_contributors-68-orange.svg?style=flat-square)](#contributors)
3030
[![PRs Welcome][prs-badge]][prs] [![Code of Conduct][coc-badge]][coc]
3131
[![Join the community on Spectrum][spectrum-badge]][spectrum]
3232

@@ -216,7 +216,7 @@ Thanks goes to these people ([emoji key][emojis]):
216216
| [<img src="https://avatars3.githubusercontent.com/u/881986?v=4" width="100px;" alt="dadamssg"/><br /><sub><b>dadamssg</b></sub>](https://github.com/dadamssg)<br />[📖](https://github.com/kentcdodds/react-testing-library/commits?author=dadamssg "Documentation") | [<img src="https://avatars0.githubusercontent.com/u/8734097?v=4" width="100px;" alt="Yazan Aabed"/><br /><sub><b>Yazan Aabed</b></sub>](https://www.yaabed.com/)<br />[📝](#blog-YazanAabeed "Blogposts") | [<img src="https://avatars0.githubusercontent.com/u/556258?v=4" width="100px;" alt="Tim"/><br /><sub><b>Tim</b></sub>](https://github.com/timbonicus)<br />[🐛](https://github.com/kentcdodds/react-testing-library/issues?q=author%3Atimbonicus "Bug reports") [💻](https://github.com/kentcdodds/react-testing-library/commits?author=timbonicus "Code") [📖](https://github.com/kentcdodds/react-testing-library/commits?author=timbonicus "Documentation") [⚠️](https://github.com/kentcdodds/react-testing-library/commits?author=timbonicus "Tests") | [<img src="https://avatars3.githubusercontent.com/u/6682655?v=4" width="100px;" alt="Divyanshu Maithani"/><br /><sub><b>Divyanshu Maithani</b></sub>](http://divyanshu.xyz)<br />[✅](#tutorial-divyanshu013 "Tutorials") [📹](#video-divyanshu013 "Videos") | [<img src="https://avatars2.githubusercontent.com/u/9116042?v=4" width="100px;" alt="Deepak Grover"/><br /><sub><b>Deepak Grover</b></sub>](https://www.linkedin.com/in/metagrover)<br />[✅](#tutorial-metagrover "Tutorials") [📹](#video-metagrover "Videos") | [<img src="https://avatars0.githubusercontent.com/u/16276358?v=4" width="100px;" alt="Eyal Cohen"/><br /><sub><b>Eyal Cohen</b></sub>](https://github.com/eyalcohen4)<br />[📖](https://github.com/kentcdodds/react-testing-library/commits?author=eyalcohen4 "Documentation") | [<img src="https://avatars3.githubusercontent.com/u/7452681?v=4" width="100px;" alt="Peter Makowski"/><br /><sub><b>Peter Makowski</b></sub>](https://github.com/petermakowski)<br />[📖](https://github.com/kentcdodds/react-testing-library/commits?author=petermakowski "Documentation") |
217217
| [<img src="https://avatars2.githubusercontent.com/u/20361668?v=4" width="100px;" alt="Michiel Nuyts"/><br /><sub><b>Michiel Nuyts</b></sub>](https://github.com/Michielnuyts)<br />[📖](https://github.com/kentcdodds/react-testing-library/commits?author=Michielnuyts "Documentation") | [<img src="https://avatars0.githubusercontent.com/u/1195863?v=4" width="100px;" alt="Joe Ng'ethe"/><br /><sub><b>Joe Ng'ethe</b></sub>](https://github.com/joeynimu)<br />[💻](https://github.com/kentcdodds/react-testing-library/commits?author=joeynimu "Code") [📖](https://github.com/kentcdodds/react-testing-library/commits?author=joeynimu "Documentation") | [<img src="https://avatars3.githubusercontent.com/u/19998290?v=4" width="100px;" alt="Kate"/><br /><sub><b>Kate</b></sub>](https://github.com/Enikol)<br />[📖](https://github.com/kentcdodds/react-testing-library/commits?author=Enikol "Documentation") | [<img src="https://avatars1.githubusercontent.com/u/11980217?v=4" width="100px;" alt="Sean"/><br /><sub><b>Sean</b></sub>](http://www.seanrparker.com)<br />[📖](https://github.com/kentcdodds/react-testing-library/commits?author=SeanRParker "Documentation") | [<img src="https://avatars2.githubusercontent.com/u/17031?v=4" width="100px;" alt="James Long"/><br /><sub><b>James Long</b></sub>](http://jlongster.com)<br />[🤔](#ideas-jlongster "Ideas, Planning, & Feedback") [📦](#platform-jlongster "Packaging/porting to new platform") | [<img src="https://avatars1.githubusercontent.com/u/10118777?v=4" width="100px;" alt="Herb Hagely"/><br /><sub><b>Herb Hagely</b></sub>](https://github.com/hhagely)<br />[💡](#example-hhagely "Examples") | [<img src="https://avatars2.githubusercontent.com/u/5779538?v=4" width="100px;" alt="Alex Wendte"/><br /><sub><b>Alex Wendte</b></sub>](http://www.wendtedesigns.com/)<br />[💡](#example-themostcolm "Examples") |
218218
| [<img src="https://avatars0.githubusercontent.com/u/6998954?v=4" width="100px;" alt="Monica Powell"/><br /><sub><b>Monica Powell</b></sub>](http://www.aboutmonica.com)<br />[📖](https://github.com/kentcdodds/react-testing-library/commits?author=M0nica "Documentation") | [<img src="https://avatars1.githubusercontent.com/u/2699953?v=4" width="100px;" alt="Vitaly Sivkov"/><br /><sub><b>Vitaly Sivkov</b></sub>](http://sivkoff.com)<br />[💻](https://github.com/kentcdodds/react-testing-library/commits?author=sivkoff "Code") | [<img src="https://avatars3.githubusercontent.com/u/7049?v=4" width="100px;" alt="Weyert de Boer"/><br /><sub><b>Weyert de Boer</b></sub>](https://github.com/weyert)<br />[🤔](#ideas-weyert "Ideas, Planning, & Feedback") [👀](#review-weyert "Reviewed Pull Requests") | [<img src="https://avatars3.githubusercontent.com/u/13613037?v=4" width="100px;" alt="EstebanMarin"/><br /><sub><b>EstebanMarin</b></sub>](https://github.com/EstebanMarin)<br />[📖](https://github.com/kentcdodds/react-testing-library/commits?author=EstebanMarin "Documentation") | [<img src="https://avatars2.githubusercontent.com/u/13953703?v=4" width="100px;" alt="Victor Martins"/><br /><sub><b>Victor Martins</b></sub>](https://github.com/vctormb)<br />[📖](https://github.com/kentcdodds/react-testing-library/commits?author=vctormb "Documentation") | [<img src="https://avatars0.githubusercontent.com/u/19773?v=4" width="100px;" alt="Royston Shufflebotham"/><br /><sub><b>Royston Shufflebotham</b></sub>](https://github.com/RoystonS)<br />[🐛](https://github.com/kentcdodds/react-testing-library/issues?q=author%3ARoystonS "Bug reports") [📖](https://github.com/kentcdodds/react-testing-library/commits?author=RoystonS "Documentation") [💡](#example-RoystonS "Examples") | [<img src="https://avatars0.githubusercontent.com/u/6834804?v=4" width="100px;" alt="chrbala"/><br /><sub><b>chrbala</b></sub>](https://github.com/chrbala)<br />[💻](https://github.com/kentcdodds/react-testing-library/commits?author=chrbala "Code") |
219-
| [<img src="https://avatars3.githubusercontent.com/u/887639?v=4" width="100px;" alt="Donavon West"/><br /><sub><b>Donavon West</b></sub>](http://donavon.com)<br />[💻](https://github.com/kentcdodds/react-testing-library/commits?author=donavon "Code") [📖](https://github.com/kentcdodds/react-testing-library/commits?author=donavon "Documentation") [🤔](#ideas-donavon "Ideas, Planning, & Feedback") [⚠️](https://github.com/kentcdodds/react-testing-library/commits?author=donavon "Tests") | [<img src="https://avatars2.githubusercontent.com/u/689081?v=4" width="100px;" alt="Richard Maisano"/><br /><sub><b>Richard Maisano</b></sub>](https://github.com/maisano)<br />[💻](https://github.com/kentcdodds/react-testing-library/commits?author=maisano "Code") | [<img src="https://avatars0.githubusercontent.com/u/5244986?v=4" width="100px;" alt="Marco Biedermann"/><br /><sub><b>Marco Biedermann</b></sub>](https://www.marcobiedermann.com)<br />[💻](https://github.com/kentcdodds/react-testing-library/commits?author=marcobiedermann "Code") [🚧](#maintenance-marcobiedermann "Maintenance") [⚠️](https://github.com/kentcdodds/react-testing-library/commits?author=marcobiedermann "Tests") | [<img src="https://avatars3.githubusercontent.com/u/93752?v=4" width="100px;" alt="Alex Zherdev"/><br /><sub><b>Alex Zherdev</b></sub>](https://github.com/alexzherdev)<br />[🐛](https://github.com/kentcdodds/react-testing-library/issues?q=author%3Aalexzherdev "Bug reports") [💻](https://github.com/kentcdodds/react-testing-library/commits?author=alexzherdev "Code") |
219+
| [<img src="https://avatars3.githubusercontent.com/u/887639?v=4" width="100px;" alt="Donavon West"/><br /><sub><b>Donavon West</b></sub>](http://donavon.com)<br />[💻](https://github.com/kentcdodds/react-testing-library/commits?author=donavon "Code") [📖](https://github.com/kentcdodds/react-testing-library/commits?author=donavon "Documentation") [🤔](#ideas-donavon "Ideas, Planning, & Feedback") [⚠️](https://github.com/kentcdodds/react-testing-library/commits?author=donavon "Tests") | [<img src="https://avatars2.githubusercontent.com/u/689081?v=4" width="100px;" alt="Richard Maisano"/><br /><sub><b>Richard Maisano</b></sub>](https://github.com/maisano)<br />[💻](https://github.com/kentcdodds/react-testing-library/commits?author=maisano "Code") | [<img src="https://avatars0.githubusercontent.com/u/5244986?v=4" width="100px;" alt="Marco Biedermann"/><br /><sub><b>Marco Biedermann</b></sub>](https://www.marcobiedermann.com)<br />[💻](https://github.com/kentcdodds/react-testing-library/commits?author=marcobiedermann "Code") [🚧](#maintenance-marcobiedermann "Maintenance") [⚠️](https://github.com/kentcdodds/react-testing-library/commits?author=marcobiedermann "Tests") | [<img src="https://avatars3.githubusercontent.com/u/93752?v=4" width="100px;" alt="Alex Zherdev"/><br /><sub><b>Alex Zherdev</b></sub>](https://github.com/alexzherdev)<br />[🐛](https://github.com/kentcdodds/react-testing-library/issues?q=author%3Aalexzherdev "Bug reports") [💻](https://github.com/kentcdodds/react-testing-library/commits?author=alexzherdev "Code") | [<img src="https://avatars0.githubusercontent.com/u/5133846?v=4" width="100px;" alt="André Matulionis dos Santos"/><br /><sub><b>André Matulionis dos Santos</b></sub>](https://twitter.com/Andrewmat)<br />[💻](https://github.com/kentcdodds/react-testing-library/commits?author=Andrewmat "Code") [💡](#example-Andrewmat "Examples") [⚠️](https://github.com/kentcdodds/react-testing-library/commits?author=Andrewmat "Tests") |
220220

221221
<!-- ALL-CONTRIBUTORS-LIST:END -->
222222

examples/__tests__/mock.react-transition-group.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,8 @@ afterEach(cleanup)
3131

3232
jest.mock('react-transition-group', () => {
3333
const FakeTransition = jest.fn(({children}) => children)
34-
const FakeCSSTransition = jest.fn(
35-
props =>
36-
props.in ? <FakeTransition>{props.children}</FakeTransition> : null,
34+
const FakeCSSTransition = jest.fn(props =>
35+
props.in ? <FakeTransition>{props.children}</FakeTransition> : null,
3736
)
3837
return {CSSTransition: FakeCSSTransition, Transition: FakeTransition}
3938
})

examples/__tests__/react-hooks.js

+93-32
Original file line numberDiff line numberDiff line change
@@ -6,53 +6,114 @@
66
*/
77
import {testHook, act, cleanup} from 'react-testing-library'
88

9-
import useCounter from '../react-hooks'
9+
import {useCounter, useDocumentTitle, useCall} from '../react-hooks'
1010

1111
afterEach(cleanup)
1212

13-
test('accepts default initial values', () => {
14-
let count
15-
testHook(() => ({count} = useCounter()))
13+
describe('useCounter', () => {
14+
test('accepts default initial values', () => {
15+
let count
16+
testHook(() => ({count} = useCounter()))
1617

17-
expect(count).toBe(0)
18-
})
18+
expect(count).toBe(0)
19+
})
1920

20-
test('accepts a default initial value for `count`', () => {
21-
let count
22-
testHook(() => ({count} = useCounter({})))
21+
test('accepts a default initial value for `count`', () => {
22+
let count
23+
testHook(() => ({count} = useCounter({})))
2324

24-
expect(count).toBe(0)
25-
})
25+
expect(count).toBe(0)
26+
})
27+
28+
test('provides an `increment` function', () => {
29+
let count, increment
30+
testHook(() => ({count, increment} = useCounter({step: 2})))
31+
32+
expect(count).toBe(0)
33+
act(() => {
34+
increment()
35+
})
36+
expect(count).toBe(2)
37+
})
38+
39+
test('provides an `decrement` function', () => {
40+
let count, decrement
41+
testHook(() => ({count, decrement} = useCounter({step: 2})))
42+
43+
expect(count).toBe(0)
44+
act(() => {
45+
decrement()
46+
})
47+
expect(count).toBe(-2)
48+
})
2649

27-
test('provides an `increment` function', () => {
28-
let count, increment
29-
testHook(() => ({count, increment} = useCounter({step: 2})))
50+
test('accepts a default initial value for `step`', () => {
51+
let count, increment
52+
testHook(() => ({count, increment} = useCounter({})))
3053

31-
expect(count).toBe(0)
32-
act(() => {
33-
increment()
54+
expect(count).toBe(0)
55+
act(() => {
56+
increment()
57+
})
58+
expect(count).toBe(1)
3459
})
35-
expect(count).toBe(2)
3660
})
3761

38-
test('provides an `decrement` function', () => {
39-
let count, decrement
40-
testHook(() => ({count, decrement} = useCounter({step: 2})))
62+
// using unmount function to check useEffect behavior when unmounting
63+
describe('useDocumentTitle', () => {
64+
test('sets a title', () => {
65+
document.title = 'original title'
66+
testHook(() => {
67+
useDocumentTitle('modified title')
68+
})
4169

42-
expect(count).toBe(0)
43-
act(() => {
44-
decrement()
70+
expect(document.title).toBe('modified title')
71+
})
72+
73+
test('returns to original title when component is unmounted', () => {
74+
document.title = 'original title'
75+
const {unmount} = testHook(() => {
76+
useDocumentTitle('modified title')
77+
})
78+
79+
unmount()
80+
expect(document.title).toBe('original title')
4581
})
46-
expect(count).toBe(-2)
4782
})
4883

49-
test('accepts a default initial value for `step`', () => {
50-
let count, increment
51-
testHook(() => ({count, increment} = useCounter({})))
84+
// using rerender function to test calling useEffect multiple times
85+
describe('useCall', () => {
86+
test('calls once on render', () => {
87+
const spy = jest.fn()
88+
testHook(() => {
89+
useCall(spy, [])
90+
})
91+
expect(spy).toHaveBeenCalledTimes(1)
92+
})
93+
94+
test('calls again if deps change', () => {
95+
let deps = [false]
96+
const spy = jest.fn()
97+
const {rerender} = testHook(() => {
98+
useCall(spy, deps)
99+
})
100+
expect(spy).toHaveBeenCalledTimes(1)
101+
102+
deps = [true]
103+
rerender()
104+
expect(spy).toHaveBeenCalledTimes(2)
105+
})
106+
107+
test('does not call again if deps are the same', () => {
108+
let deps = [false]
109+
const spy = jest.fn()
110+
const {rerender} = testHook(() => {
111+
useCall(spy, deps)
112+
})
113+
expect(spy).toHaveBeenCalledTimes(1)
52114

53-
expect(count).toBe(0)
54-
act(() => {
55-
increment()
115+
deps = [false]
116+
rerender()
117+
expect(spy).toHaveBeenCalledTimes(1)
56118
})
57-
expect(count).toBe(1)
58119
})

examples/react-hooks.js

+18-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,25 @@
1-
import {useState} from 'react'
1+
import {useState, useEffect} from 'react'
22

3-
function useCounter({initialCount = 0, step = 1} = {}) {
3+
export function useCounter({initialCount = 0, step = 1} = {}) {
44
const [count, setCount] = useState(initialCount)
55
const increment = () => setCount(c => c + step)
66
const decrement = () => setCount(c => c - step)
77
return {count, increment, decrement}
88
}
99

10-
export default useCounter
10+
export function useDocumentTitle(title) {
11+
const [originalTitle, setOriginalTitle] = useState(document.title)
12+
useEffect(() => {
13+
setOriginalTitle(document.title)
14+
document.title = title
15+
return () => {
16+
document.title = originalTitle
17+
}
18+
}, [title])
19+
}
20+
21+
export function useCall(callback, deps) {
22+
useEffect(() => {
23+
callback()
24+
}, deps)
25+
}

src/__tests__/test-hook.js

+27-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {useState} from 'react'
1+
import {useState, useEffect} from 'react'
22
import 'jest-dom/extend-expect'
33
import {testHook, cleanup} from '../'
44

@@ -12,3 +12,29 @@ test('testHook calls the callback', () => {
1212
test('confirm we can safely call a React Hook from within the callback', () => {
1313
testHook(() => useState())
1414
})
15+
test('returns a function to unmount component', () => {
16+
let isMounted
17+
const {unmount} = testHook(() => {
18+
useEffect(() => {
19+
isMounted = true
20+
return () => {
21+
isMounted = false
22+
}
23+
})
24+
})
25+
expect(isMounted).toBe(true)
26+
unmount()
27+
expect(isMounted).toBe(false)
28+
})
29+
test('returns a function to rerender component', () => {
30+
let renderCount = 0
31+
const {rerender} = testHook(() => {
32+
useEffect(() => {
33+
renderCount++
34+
})
35+
})
36+
37+
expect(renderCount).toBe(1)
38+
rerender()
39+
expect(renderCount).toBe(2)
40+
})

src/index.js

+9-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,15 @@ function TestHook({callback}) {
6767
}
6868

6969
function testHook(callback) {
70-
render(<TestHook callback={callback} />)
70+
const {unmount, rerender: rerenderComponent} = render(
71+
<TestHook callback={callback} />,
72+
)
73+
return {
74+
unmount,
75+
rerender: () => {
76+
rerenderComponent(<TestHook callback={callback} />)
77+
},
78+
}
7179
}
7280

7381
function cleanup() {

0 commit comments

Comments
 (0)