-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
React recipe #747
React recipe #747
Changes from 3 commits
5aac318
7901017
4c68745
142b7f2
543e9c2
a729aeb
d26ba95
48c9e43
f0762dd
9a1ff8c
2f83c2a
2fb1369
ec58ef4
2952f97
e537343
590badb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
# Testing React components | ||
|
||
This recipe is giving guidelines to test React components. | ||
|
||
## Setting up Babel | ||
|
||
The first thing you need to do is to set up `babel` to transpile JSX code from the tests. To do that, I'd recommend the [babelrc recipe](https://github.com/sindresorhus/ava/blob/master/docs/recipes/babelrc.md) using `babel-preset-react`. You can also have a look at this sample project configuration: https://github.com/adriantoine/ava-enzyme-demo | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Linkify There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. configuration => config |
||
|
||
## Enzyme | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Needs to be more descriptive. |
||
|
||
Let's see first how to implement how to use ava with one of the most popular React testing library: [enzyme](https://github.com/airbnb/enzyme). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
ava => AVA |
||
|
||
If you only plan to use `shallow` component rendering, you don't need extra setup. First install `enzyme`: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
```js | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this need to be highlighted as There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. console instead of js (is better) |
||
npm i --save-dev enzyme react-addons-test-utils react-dom | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
``` | ||
|
||
and you can use enzyme straight away (example from the enzyme readme): | ||
|
||
```js | ||
import test from 'ava'; | ||
import React from 'react'; | ||
import { shallow } from 'enzyme'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
import sinon from 'sinon'; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove empty line |
||
import MyComponent from '../'; | ||
import Foo from '../../Foo'; | ||
|
||
test('renders three <Foo /> components', t => { | ||
const wrapper = shallow(<MyComponent />); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
t.is(wrapper.find(Foo).length, 3); | ||
}); | ||
|
||
test('renders an `.icon-star`', t => { | ||
const wrapper = shallow(<MyComponent />); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
t.is(wrapper.find('.icon-star').length, 1); | ||
}); | ||
|
||
test('renders children when passed in', t => { | ||
const wrapper = shallow( | ||
<MyComponent> | ||
<div className="unique" /> | ||
</MyComponent> | ||
); | ||
t.truthy(wrapper.contains(<div className="unique" />); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use |
||
}); | ||
|
||
test('simulates click events', t => { | ||
const onButtonClick = sinon.spy(); | ||
const wrapper = shallow( | ||
<Foo onButtonClick={onButtonClick} /> | ||
); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
wrapper.find('button').simulate('click'); | ||
t.truthy(onButtonClick.calledOnce); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
}); | ||
``` | ||
|
||
`enzyme` also has a `mount` and `render` helper to test in an actual browser environment, if you want to use these helpers, you will have to setup a browser environment, to do so, you should check out the [browser testing recipe](https://github.com/sindresorhus/ava/blob/master/docs/recipes/browser-testing.md). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
Here is a simple and minimal example of testing react components using `ava` and `enzyme` along with browser testing: https://github.com/adriantoine/ava-enzyme-demo | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. react => React There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't put in plain links, linkify some text instead. |
||
|
||
## Using JSX helpers | ||
|
||
There is another approach to testing React component, which is to use the [`react-element-to-jsx-string`](https://github.com/algolia/react-element-to-jsx-string) package to compare DOM trees as strings, like [`expect-jsx`](https://github.com/algolia/expect-jsx). [You can use `expect-jsx` with ava](https://github.com/sindresorhus/ava/issues/186#issuecomment-161317068) however it is nicer to use ava assertions and only rely on helpers. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ava => AVA |
||
|
||
To do so you can use the [`jsx-test-helpers`](https://github.com/MoOx/jsx-test-helpers) library: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Might be worth it to mention that |
||
|
||
```js | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Replace |
||
npm i --save-dev jsx-test-helpers | ||
``` | ||
|
||
and test your React components: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And |
||
```js | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a linebreak between line |
||
import test from 'ava'; | ||
import React from 'react'; | ||
import { noop, renderJSX, JSX } from 'jsx-test-helpers'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
import MyComponent from '../'; | ||
import Foo from '../../Foo'; | ||
|
||
test('renders three <Foo /> components', t => { | ||
const actual = renderJSX(<MyComponent />); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
const expected = JSX( | ||
<div onClick={ noop } className='MyComponent'> | ||
<span className='icon-star'/> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Inconsistent quote usage. You used double-quotes earlier. |
||
<Foo/> | ||
<Foo/> | ||
<Foo/> | ||
</div> | ||
); | ||
t.is(actual, expected); | ||
}); | ||
``` | ||
|
||
Note that you have to use variables like `actual` and `expected` because `power-assert` doesn't handle JSX correctly. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you linkify |
||
|
||
You can find annotated test file [here](https://github.com/MoOx/jsx-test-helpers/blob/master/src/__tests__/index.js) with more examples. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't really have much value. It's just a longer description of the title. I would drop it or come up with something else.