Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use react-hooks-testing-library to test hooks #1259

Merged
merged 2 commits into from Apr 25, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 21 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Expand Up @@ -74,6 +74,8 @@
"prettier": "^1.16.4",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-hooks-testing-library": "^0.5.0",
"react-test-renderer": "^16.8.6",
timdorr marked this conversation as resolved.
Show resolved Hide resolved
"react-testing-library": "^5.9.0",
"redux": "^4.0.1",
"rimraf": "^2.6.3",
Expand Down
133 changes: 38 additions & 95 deletions test/hooks/useActions.spec.js
@@ -1,6 +1,8 @@
/*eslint-disable react/display-name*/
timdorr marked this conversation as resolved.
Show resolved Hide resolved

import React from 'react'
import { createStore } from 'redux'
import * as rtl from 'react-testing-library'
import { renderHook } from 'react-hooks-testing-library'
import { Provider as ProviderMock, useActions } from '../../src/index.js'

describe('React', () => {
Expand Down Expand Up @@ -28,58 +30,29 @@ describe('React', () => {
dispatchedActions = []
})

afterEach(() => rtl.cleanup())

it('supports a single action creator', () => {
const Comp = () => {
const inc1 = useActions(() => ({ type: 'inc1' }))

return (
<>
<button id="bInc1" onClick={inc1} />
</>
)
}

const { container } = rtl.render(
<ProviderMock store={store}>
<Comp />
</ProviderMock>
const { result } = renderHook(
() => useActions(() => ({ type: 'inc1' })),
{ wrapper: props => <ProviderMock {...props} store={store} /> }
)

const bInc1 = container.querySelector('#bInc1')

rtl.fireEvent.click(bInc1)
result.current()

expect(dispatchedActions).toEqual([{ type: 'inc1' }])
})

it('supports an object of action creators', () => {
const Comp = () => {
const { inc1, inc2 } = useActions({
inc1: () => ({ type: 'inc1' }),
inc2: () => ({ type: 'inc', amount: 2 })
})

return (
<>
<button id="bInc1" onClick={inc1} />
<button id="bInc2" onClick={inc2} />
</>
)
}

const { container } = rtl.render(
<ProviderMock store={store}>
<Comp />
</ProviderMock>
const { result } = renderHook(
() =>
useActions({
inc1: () => ({ type: 'inc1' }),
inc2: () => ({ type: 'inc', amount: 2 })
}),
{ wrapper: props => <ProviderMock {...props} store={store} /> }
)

const bInc1 = container.querySelector('#bInc1')
const bInc2 = container.querySelector('#bInc2')

rtl.fireEvent.click(bInc1)
rtl.fireEvent.click(bInc2)
result.current.inc1()
result.current.inc2()

expect(dispatchedActions).toEqual([
{ type: 'inc1' },
Expand All @@ -88,31 +61,17 @@ describe('React', () => {
})

it('supports an array of action creators', () => {
const Comp = () => {
const [inc1, inc2] = useActions([
() => ({ type: 'inc1' }),
() => ({ type: 'inc', amount: 2 })
])

return (
<>
<button id="bInc1" onClick={inc1} />
<button id="bInc2" onClick={inc2} />
</>
)
}

const { container } = rtl.render(
<ProviderMock store={store}>
<Comp />
</ProviderMock>
const { result } = renderHook(
() =>
useActions([
() => ({ type: 'inc1' }),
() => ({ type: 'inc', amount: 2 })
]),
{ wrapper: props => <ProviderMock {...props} store={store} /> }
)

const bInc1 = container.querySelector('#bInc1')
const bInc2 = container.querySelector('#bInc2')

rtl.fireEvent.click(bInc1)
rtl.fireEvent.click(bInc2)
result.current[0]()
result.current[1]()

expect(dispatchedActions).toEqual([
{ type: 'inc1' },
Expand All @@ -133,37 +92,21 @@ describe('React', () => {
const store = createStore(reducer)
dispatchedActions = []

const Comp = () => {
const { adjust } = useActions({
adjust: (amount, isAdd = true) => ({
type: 'adjust',
amount,
isAdd
})
})

return (
<>
<button id="bInc1" onClick={() => adjust(1)} />
<button id="bInc2" onClick={() => adjust(2)} />
<button id="bDec1" onClick={() => adjust(1, false)} />
</>
)
}

const { container } = rtl.render(
<ProviderMock store={store}>
<Comp />
</ProviderMock>
const { result } = renderHook(
() =>
useActions({
adjust: (amount, isAdd = true) => ({
type: 'adjust',
amount,
isAdd
})
}),
{ wrapper: props => <ProviderMock {...props} store={store} /> }
)

const bInc1 = container.querySelector('#bInc1')
const bInc2 = container.querySelector('#bInc2')
const bDec1 = container.querySelector('#bDec1')

rtl.fireEvent.click(bInc1)
rtl.fireEvent.click(bInc2)
rtl.fireEvent.click(bDec1)
result.current.adjust(1)
result.current.adjust(2)
result.current.adjust(1, false)

expect(dispatchedActions).toEqual([
{ type: 'adjust', amount: 1, isAdd: true },
Expand Down
23 changes: 7 additions & 16 deletions test/hooks/useDispatch.spec.js
@@ -1,30 +1,21 @@
/*eslint-disable react/display-name*/

import React from 'react'
import { createStore } from 'redux'
import * as rtl from 'react-testing-library'
import { renderHook } from 'react-hooks-testing-library'
import { Provider as ProviderMock, useDispatch } from '../../src/index.js'

const store = createStore(c => c + 1)

describe('React', () => {
describe('hooks', () => {
describe('useDispatch', () => {
afterEach(() => rtl.cleanup())

it("returns the store's dispatch function", () => {
let dispatch

const Comp = () => {
dispatch = useDispatch()
return <div />
}

rtl.render(
<ProviderMock store={store}>
<Comp />
</ProviderMock>
)
const { result } = renderHook(() => useDispatch(), {
wrapper: props => <ProviderMock {...props} store={store} />
})

expect(dispatch).toBe(store.dispatch)
expect(result.current).toBe(store.dispatch)
})
})
})
Expand Down
40 changes: 15 additions & 25 deletions test/hooks/useRedux.spec.js
@@ -1,50 +1,40 @@
/*eslint-disable react/display-name*/
/*eslint-disable react/prop-types*/

import React from 'react'
import { createStore } from 'redux'
import * as rtl from 'react-testing-library'
import { renderHook, act } from 'react-hooks-testing-library'
import { Provider as ProviderMock, useRedux } from '../../src/index.js'

describe('React', () => {
describe('hooks', () => {
describe('useRedux', () => {
let store
let renderedItems = []

beforeEach(() => {
store = createStore(({ count } = { count: -1 }) => ({
count: count + 1
}))
renderedItems = []
})

afterEach(() => rtl.cleanup())

it('selects the state and binds action creators', () => {
const Comp = () => {
const [count, { inc }] = useRedux(s => s.count, {
inc: () => ({ type: '' })
})
renderedItems.push(count)
return (
<>
<div>{count}</div>
<button id="bInc" onClick={inc} />
</>
)
}

const { container } = rtl.render(
<ProviderMock store={store}>
<Comp />
</ProviderMock>
const { result } = renderHook(
() =>
useRedux(s => s.count, {
inc: () => ({ type: '' })
}),
{
wrapper: props => <ProviderMock {...props} store={store} />
}
)

const bInc = container.querySelector('#bInc')
expect(result.current[0]).toEqual(0)

rtl.fireEvent.click(bInc)
act(() => {
result.current[1].inc()
})

expect(renderedItems).toEqual([0, 1])
expect(result.current[0]).toEqual(1)
})
})
})
Expand Down
12 changes: 3 additions & 9 deletions test/hooks/useReduxContext.spec.js
@@ -1,21 +1,15 @@
import React from 'react'
import * as rtl from 'react-testing-library'
import { renderHook } from 'react-hooks-testing-library'
import { useReduxContext } from '../../src/hooks/useReduxContext'

describe('React', () => {
describe('hooks', () => {
describe('useReduxContext', () => {
afterEach(() => rtl.cleanup())

it('throws if component is not wrapped in provider', () => {
const spy = jest.spyOn(console, 'error').mockImplementation(() => {})

const Comp = () => {
useReduxContext()
return <div />
}
const { result } = renderHook(() => useReduxContext())

expect(() => rtl.render(<Comp />)).toThrow(
expect(result.error.message).toMatch(
/could not find react-redux context value/
)

Expand Down