I’m going to do an experiment on a branch to see if I can make the interface for testing a little easier to read. I want something a bit more like assert_select in Rails.
Let’s see now. Pretending it’s magic…
test('shows the first blog post', async () => {
const component = await mount(<Application />)
check(component).has(
{
'.site-name': 'Blogging',
'.post .title': 'React on Rails',
'.post .body': 'I can use React with Rails.',
}
)
})
Or, how about this?
test('also shows the first blog post', async () => {
const component = await mount(<Application />)
assert_select(component, '.site-name', 'Blogging')
assert_select(component, '.post .title', 'React on Rails')
assert_select(component, '.post .body', 'I can use React with Rails.')
})
assert_select in Rails allows nesting. Maybe something like this?
test('shows the first blog post with nesting', async () => {
const component = await mount(<Application />)
assert_select(component, '.site-name', 'Blogging')
assert_select(component, '.post', match => {
assert_select(match, '.title', 'React on Rails')
assert_select(match, '.body', 'I can use React with Rails.')
})
})
Let’s try the simple (non-nested) version for a while to see how it feels. Here’s a quick implementation.
export function assert_select(component, selector, expectation=1) {
const selected = component.find(selector)
switch(typeof(expectation)) {
case 'string':
expect(selected.text()).toEqual(expectation)
break
case 'number':
expect(selected.length).toEqual(expectation)
break
default:
expect(expectation).toEqual('string or number')
break
}
}
If the expectation is a string, we’ll see if text matches. If it’s a number, we’ll check the number of matches. If you skip the expectation, we’ll just check that there is a match.
Let’s see how it goes. I’ll extract this into a ReactHelper along with a wrapper function for mount() that I will call display().
// test/javascript/helpers/ReactHelper.jsx
import {configure, mount} from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
configure({ adapter: new Adapter() })
export function display(component) {
return mount(component)
}
This hides away the fiddly code to initialise enzyme and (SPOILERS) it also provides a handy place to initialise global state should we need that later.
I’ve updated all the tests to use assert_select and the setup code in ReactHelper.
Tidy is good.
