react-webpack-generators / generator-react-webpack

Yeoman generator for ReactJS and Webpack
http://newtriks.com/2013/12/31/automating-react-with-yeoman-and-grunt/
MIT License
2.88k stars 355 forks source link

Question: How to use spies/mocks/stubs within stack, as well as properly Unit test components #216

Closed AdamT closed 8 years ago

AdamT commented 8 years ago

This generator comes with Chai + Mocha but I'm finding that these packages aren't ideal for testing React (could be wrong). I'm finding it difficult to stub component methods or call on state. This may be related to the helper createComponent which uses createRenderer.

Is there a best practice or example on how to properly unit test components with this stack? This means only testing an existing component and not having it leak child components, as well as making outbound http requests.

Thank you

weblogixx commented 8 years ago

Hi @AdamT,

the answer would take a bit longer, but just in short:

Chai and Mocha are a perfect team for testing. I got test suites here at work that rely on this toolchain and we got more then 800 tests (counted with flux store tests and utils) that we are using this generator for.

When we implemented the createComponent stuff, react 0.13 was just released and it gave us the shallowRenderer, which should be perfect for unit tests of dumb (stateless) components. With it, you can test the created dom one level deep.

That does not make testing easier with react, as you may still have to use the react-addons-testutils package directly (e.g. for rendering the full component into the dom).

We are currently moving away from the current approach in favour of enzyme (http://airbnb.io/enzyme/), which makes testing react components a breeze. You may try the current version of the underlying template (https://github.com/weblogixx/react-webpack-template/tree/2.x) of this generator, it has this stuff already included. It still uses mocha + chai, but without karma (a virtual (js)dom is used instead).

For testing components da do stuff like requests (http, websocket) or have other behaviour that you do not want to run while testing, have a look at sinon. Set up sinon stubs before the unwanted behaviour is triggered and reset the stubs afterwards. With this approach, your scripts will not call the original function (e.g. ajax request), but stub it away so you can assert its function without touching the core.

Hope this helps.