React Stub
A stubbing tool that leads to safer and more maintainable React unit tests.
How it works
You create a stub component out of a real component. The stub is just a normal React component -- you can render it, nest it, inspect its properties, do whatever you want. Example:
// Pretend this is something in your app:; ;let LoginStub = ;
Install
npm install --save-dev react-stub
Requirements
Safer and more maintainable tests
Stubs and mocks are generally risky in dynamic languages such as JavaScript because you have to keep track of interface refactoring in your head and that's hard. This leads to a maintainance burden and in the worst case scenario you might have a passing test suite yet a failing application. React Stub attempts to solve these problems.
Here is an overview of error feedback you get when running tests:
- If the component you've stubbed out gets moved or renamed, you'll see an error.
- If you try to set a property on the stub that isn't in the real component's PropTypes then you'll get an error.
- If you assign an invalid property value on the stub component you'll see a PropTypes validation error.
- If a component forgets to declare a required property on a stubbed sub-component, you'll also see a PropTypes validation error.
Make sure your app uses components correctly
A good case for stubbed components is when you have one component that depends on another but you want to unit test each of them independently. Stubbing out the one you're not testing helps you focus on the interface of the dependent component, which is typically its properties. This also helps keep your test suite lean and fast.
Imagine you have an App
component that relies on a Login
component. If you want
to test App
in isolation, the first thing you need to do is
re-design your App
class to accept a stubbed dependency:
; // Import the real component for reference.; static propTypes = Login: PropTypesfuncisRequired static defaultProps = // When not testing, the real Login is used. Login: DefaultLogin { let Login = thispropsLogin; return <Login/>; }
This component design allows you to inject a stub component while testing, like this:
// Pretend these are custom components for your app.;; ;; let LoginStub = ;ReactTestUtils;
If the stub gets used incorrectly, you'll see an exception when the top level component gets rendered. For example, if you pass an unexpected attribute, you'll see an error:
ReactTestUtils;
...
reactStub:Login does not accept property userId
Deeper property inspection
If you want to go beyond simply verifying the PropTypes of the stubbed component, you can use typical React testing approaches. For example:
// Pretend these are custom components for your app.;; ;; let LoginStub = ;let renderedApp = ReactTestUtils; let renderedLogin = ReactTestUtils; // You could now make assertions about `renderedLogin.props` ...
Development
Clone the source, install NodeJS, and run this from the source directory to install the dependency modules:
npm install
Make sure you have grunt installed and on your path. Otherwise, run this:
npm install -g grunt
To run the tests each time you edit a file, run:
grunt watch-test
To run a test suite once, run:
grunt test
To check for lint errors, run:
grunt eslint
To build a distribution from source, run:
grunt build
Distribution
To create a new release:
- Increment the version in
package.json
. - Make sure the release history section in
README.md
is up to date. - Commit and push your changes.
- Tag the version (like
git tag 0.0.1
) and push the tag withgit push --tags
. - Run
grunt build
to create a common JS distribution (in thedist
folder). - Run
npm publish
.
Release history
-
0.0.2
(2015-12-14)- Provide a proper common JS distribution, i.e. no transpilation required.
-
0.0.1
(2015-12-14)- Initial release!