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.