Skip to content
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

Merged
merged 16 commits into from
Apr 27, 2016
Merged
Changes from 3 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
98 changes: 98 additions & 0 deletions docs/recipes/react.md
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.
Copy link
Member

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.


## 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
Copy link
Member

Choose a reason for hiding this comment

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

Linkify babel-preset-react and linkify sample project configuration instead of showing the full URL.

Copy link
Member

Choose a reason for hiding this comment

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

configuration => config


## Enzyme
Copy link
Member

Choose a reason for hiding this comment

The 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).
Copy link
Member

Choose a reason for hiding this comment

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

Let's see first => Let's first see

ava => AVA


If you only plan to use `shallow` component rendering, you don't need extra setup. First install `enzyme`:
Copy link
Member

Choose a reason for hiding this comment

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

need extra setup => need any extra setup

Copy link
Member

Choose a reason for hiding this comment

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

First install enzyme: should be on a new line.


```js
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this need to be highlighted as js?

Copy link
Contributor

Choose a reason for hiding this comment

The 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
Copy link
Member

Choose a reason for hiding this comment

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

npm i => npm install

```

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';
Copy link
Member

Choose a reason for hiding this comment

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

import {shallow} from 'enzyme';

import sinon from 'sinon';

Copy link
Member

Choose a reason for hiding this comment

The 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 />);
Copy link
Contributor

Choose a reason for hiding this comment

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

const wrapper = shallow(<MyComponent/>);

t.is(wrapper.find(Foo).length, 3);
});

test('renders an `.icon-star`', t => {
const wrapper = shallow(<MyComponent />);
Copy link
Contributor

Choose a reason for hiding this comment

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

const wrapper = shallow(<MyComponent/>);

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" />);
Copy link
Member

Choose a reason for hiding this comment

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

Use t.true and missing a )

});

test('simulates click events', t => {
const onButtonClick = sinon.spy();
const wrapper = shallow(
<Foo onButtonClick={onButtonClick} />
);
Copy link
Contributor

Choose a reason for hiding this comment

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

const wrapper = shallow(<Foo onButtonClick={() => t.pass()}/>

wrapper.find('button').simulate('click');
t.truthy(onButtonClick.calledOnce);
Copy link
Member

Choose a reason for hiding this comment

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

t.true

});
```

`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).
Copy link
Member

Choose a reason for hiding this comment

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

environment, to do so, => environment. To do so,


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
Copy link
Member

Choose a reason for hiding this comment

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

react => React

Copy link
Member

Choose a reason for hiding this comment

The 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.
Copy link
Member

Choose a reason for hiding this comment

The 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:
Copy link

Choose a reason for hiding this comment

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

Might be worth it to mention that jsx-test-helpers has react-addons-test-utils as an dependency so you don't have to npm install it yourself. (Or to add it to the install clause regardless if you are going use the TestUtils)


```js
Copy link
Contributor

Choose a reason for hiding this comment

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

Replace js by console

npm i --save-dev jsx-test-helpers
```

and test your React components:
Copy link
Member

Choose a reason for hiding this comment

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

And

```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 { noop, renderJSX, JSX } from 'jsx-test-helpers';
Copy link
Contributor

Choose a reason for hiding this comment

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

import {noop, renderJSX, JSX} from 'jsx-test-helpers':


import MyComponent from '../';
import Foo from '../../Foo';

test('renders three <Foo /> components', t => {
const actual = renderJSX(<MyComponent />);
Copy link
Contributor

Choose a reason for hiding this comment

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

const actual = renderJSX(<MyComponent/>); (notice removal of the space in closing tag).

const expected = JSX(
<div onClick={ noop } className='MyComponent'>
<span className='icon-star'/>
Copy link
Member

Choose a reason for hiding this comment

The 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.
Copy link
Member

Choose a reason for hiding this comment

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

Can you linkify power-assert doesn't handle JSX correctly to the relevant power-assert issue?


You can find annotated test file [here](https://github.com/MoOx/jsx-test-helpers/blob/master/src/__tests__/index.js) with more examples.