Skip to content

React recipe #747

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

Merged
merged 16 commits into from
Apr 27, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 143 additions & 0 deletions docs/recipes/react.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# Testing React components

## Setting up Babel

The first thing you need to do is to set up `babel` to transpile JSX code from the tests by adding an AVA section to your `package.json`:

```json
{
"ava": {
"require": ["babel-register"]
},
"babel": {
"presets": ["react"]
}
}
```

You can find more information about setting up `babel` with AVA in the [babelrc recipe](https://github.com/sindresorhus/ava/blob/master/docs/recipes/babelrc.md).

## Using [Enzyme](https://github.com/airbnb/enzyme)

Let's first see how to use AVA with one of the most popular React testing libraries: [Enzyme](https://github.com/airbnb/enzyme).

If you only plan to use [shallow component rendering](https://facebook.github.io/react/docs/test-utils.html#shallow-rendering), you don't need any extra setup.

First install [Enzyme required packages](https://github.com/airbnb/enzyme/#installation):

```console
$ npm install --save-dev enzyme react-addons-test-utils react-dom
```

And you can use Enzyme straight away:

```js
import test from 'ava';
import React from 'react';
import {shallow} from 'enzyme';

const Foo = ({children}) =>
<div className="Foo">
<span className="bar">bar</span>
{children}
<span className="bar">bar</span>
</div>;

Foo.propTypes = {
children: React.PropTypes.any
};

test('has a .Foo class name', t => {
const wrapper = shallow(<Foo/>);
t.true(wrapper.hasClass('Foo'));
});

test('renders two `.Bar`', t => {
const wrapper = shallow(<Foo/>);
t.is(wrapper.find('.bar').length, 2);
});

test('renders children when passed in', t => {
const wrapper = shallow(
<Foo>
<div className="unique"/>
</Foo>
);
t.true(wrapper.contains(<div className="unique"/>));
});
```

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. Check out the [browser testing recipe](https://github.com/sindresorhus/ava/blob/master/docs/recipes/browser-testing.md) on how to do so.

To see an example of AVA working together with Enzyme, set up for browser testing, have a look at [this sample project](https://github.com/adriantoine/ava-enzyme-demo).

This is a basic example about how to integrate Enzyme with AVA. For more information about using Enzyme for unit testing React component, have a look at [Enzyme's documentation](http://airbnb.io/enzyme/).

## Using JSX helpers

Another approach to testing React component 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. [`jsx-test-helpers`](https://github.com/MoOx/jsx-test-helpers) is a nice library handling [shallow component rendering](https://facebook.github.io/react/docs/test-utils.html#shallow-rendering) and converting JSX to string in order to test React components using AVA assertions.

```console
$ npm install --save-dev jsx-test-helpers
```

Usage example:

```js
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a linebreak between line 70 and 71.

import test from 'ava';
import React from 'react';
import {renderJSX, JSX} from 'jsx-test-helpers';

const Foo = ({children}) =>
<div className="Foo">
<span className="bar">bar</span>
{children}
<span className="bar">bar</span>
</div>;

Foo.propTypes = {
children: React.PropTypes.any
};

test('renders correct markup', t => {
const actual = renderJSX(<Foo/>);
const expected = JSX(
<div className="Foo">
<span className="bar">bar</span>
<span className="bar">bar</span>
</div>
);
t.is(actual, expected);
});

test('renders children when passed in', t => {
const actual = renderJSX(
<Foo>
<div className="unique"/>
</Foo>
);
const expected = JSX(
<div className="Foo">
<span className="bar">bar</span>
<div className="unique"/>
<span className="bar">bar</span>
</div>
);
t.is(actual, expected);
});
```

Note that you have to use variables like `actual` and `expected` because [`power-assert` doesn't handle JSX correctly](https://github.com/power-assert-js/power-assert/issues/34).

This is a basic example about how to use `jsx-test-helpers` with AVA. To see a more advanced usage of this library, have a look at [this annotated test file](https://github.com/MoOx/jsx-test-helpers/blob/master/src/__tests__/index.js).

[This sample project](https://github.com/MoOx/jsx-test-helpers) shows a basic and minimal setup of AVA with `jsx-test-helpers`.

## Using other assertion libraries

In AVA, you can use any assertion library and there is already a few out there allowing to test React components. Here is a list of assertion libraries working well with AVA:
- [`expect-jsx`](https://github.com/algolia/expect-jsx) ([Example](https://github.com/sindresorhus/ava/issues/186#issuecomment-161317068))
- [`unexpected-react`](https://github.com/bruderstein/unexpected-react) ([Sample project with an output example](https://github.com/adriantoine/ava-unexpected-react-demo))

## Reference
- [In depth guide of setting up AVA with code coverage on a React project](https://github.com/kentcdodds/react-ava-workshop)
1 change: 1 addition & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -919,6 +919,7 @@ It's the [Andromeda galaxy](https://simple.wikipedia.org/wiki/Andromeda_galaxy).
- [Browser testing](docs/recipes/browser-testing.md)
- [TypeScript](docs/recipes/typescript.md)
- [Configuring Babel](docs/recipes/babelrc.md)
- [Testing React components](docs/recipes/react.md)

## Support

Expand Down