Last active
May 8, 2018 20:30
-
-
Save chrisregner/ff0c65bb9786b0037f735e965cd47170 to your computer and use it in GitHub Desktop.
A function which greatly reduces the boilerplate when testing the inner structure of a React component given a certain set of props/state. It uses Enzyme and Chai's assert (can be replaced with any other assertion library)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { assert } from 'chai' | |
import { curry, forEachObjIndexed } from 'ramda' | |
const find = (wrapper, matcher) => | |
wrapper.findWhere(x => | |
x.prop('data-test') && | |
x.prop('data-test') | |
.trim() | |
.split(' ') | |
.includes(matcher) | |
) | |
/* | |
// sample usage: | |
const MyCmpt = () => | |
<div> | |
<div data-test='foo'>FOO!</div> | |
<div data-test='bar baz'>BAR! BAZ?</div> | |
</div> | |
const findInMyCmpt = findTestComponent(shallow(<MyCmpt />)) | |
findInMyCmpt('foo') // returns wrapper for <div data-test='foo'>FOO!</div> | |
findInMyCmpt('baz') // returns wrapper for <div data-test='bar baz'>BAR! BAZ?</div> | |
*/ | |
export const findTestComponent = curry( | |
(wrapper, matcher) => { | |
if (typeof matcher === 'string') | |
return find(wrapper, matcher) | |
if (Array.isArray(matcher)) | |
return matcher.reduce( | |
(currentWrapper, matcher) => find(currentWrapper, matcher), | |
wrapper | |
) | |
} | |
) | |
/* | |
// sample usage: | |
testSubComponents(postPage, { | |
// assert that 3 element that matches [data-test='post-item'] is rendered and... | |
'post-item': [3, (postItems) => { | |
// assert that each post item renders the correct data | |
postItems.forEach((postItem, i) => { | |
assert.equal(postItem.text(), posts[i], | |
`expected post item at index ${i} to render ${posts[i]}`) | |
}) | |
}], | |
// assert that 1 element that matches [data-test='load-more-btn'] is rendered and... | |
'load-more-btn: [1, (loadMore) => { | |
// assert that correct handler is called when it is clicked | |
assert.equal(handleLoadMore.getCallCount(), 0, | |
'expected handleLoader to have been called 0 times before clicking the button') | |
loadMore.simulate('click') | |
assert.equal(handleLoadMore.getCallCount(), 1, | |
'expected handleLoader to have been called 1 time after clicking the button') | |
}], | |
// assert that none of the following component is rendered | |
'loader': 0, | |
'error': 0, | |
'write-your-first-post': 0, | |
}) | |
*/ | |
export const testSubComponents = (wrapper, expectations) => { | |
forEachObjIndexed((expectation, matcher) => { | |
const componentCount = typeof expectation === 'number' ? expectation : expectation[0] | |
const customCondition = typeof expectation === 'number' ? () => {} : expectation[1] | |
const subwrapper = find(wrapper, matcher) | |
customCondition(subwrapper) | |
assert.equal( | |
subwrapper.length, | |
componentCount, | |
`expected ${componentCount} ${matcher} to be rendered` | |
) | |
}, expectations) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
To put in another way, it reduces this kind of tests:
to this: