Key Motivations for Jest
The "easier" part boiled down to three primary features:
- All dependencies are mocked by default
- Ease of setup and configuration
- Auto-magically finds and runs all your tests; no registration required
To Mock, or Not To Mock? Shouldn't be a Question
This seems fine, but only because that is the way everyone else does it. The vast majority of the time you need to mock all dependencies with the exception of the subject under test. Not mocking a particular dependency is typically an edge-case. If we typically mock everything but the SUT, then why do frameworks have us do the exact opposite; not mock the SUT and explicitly define our mocks for everything else?
Here I agree with Jest's approach. Jest automatically mocks all dependencies unless otherwise specified. This allows us to only setup our mocks for what is relevant to the test in question, but still have all other dependencies be fakes. It also means that changing interactions with collaborators is quicker and easier. No need for unnecessary setup of a fake; it's setup for you out the gate.
Configuration has Never Been Easier
If you use mocha/karma with CommonJS modules, then you know that module paths can sometimes bite you. This is especially true when configuring karma. I have come across a variety of directory structures and with each one I have run into some sort of path related issue when configuring the client-side testing stack.
- Create your karma config file
- Include mocha, sinon, and chai karma frameworks, as well as the plugins for them (karma-mocha, karma-sinon, karma-chai, and karma-sinon-chai).
- Don't forget to include a karma plugin for your browser (IE, PhantomJS, Chrome, etc.)
- Include your source files and test files by registering them with karma
- Don't forget to not load your source files otherwise they may be loaded twice with errors
- Include third-party dependencies to be used as CommonJS modules
- Using bower? Either explicitly add every bower package's main file to the config file or write custom code to pull them and translate them properly
- Using a CDN for some? Don't forget to include these explicitly
- Don't forget to exclude your node_modules folder from being processed as CommonJS modules
- Don't forget to include configuration for the plugins that enable you to use CommonJS with karma (karma-common-js).
- Create a test. Mock any requires needed for the module and test.
- Create a
__tests__directory to contain your tests.
- Create a test. Tell jest not to mock the SUT and setup any fakes required.
jestfrom the command line.
What about the third-party dependencies? What if my module and/or test needed jQuery from a bower_components directory? Or a CDN? How does it know where jQuery is coming from? The simple answer is it doesn't matter. It's mocked!
What about telling it where the test files are or where the source files are? Jest takes care of that also by using the convention that all your tests are in the
What about the DOM manipulations? It utilizes jsdom to allow the testing of DOM operations.
Overall, I am quite impressed with Jest. I am impressed enough to adopt it as my personal standard for client-side unit testing and recommend it to any one else working with TDD for front-end development. However, there was one noticeable drawback: it is a little slow to run your tests. Compared to mocha/karma, it takes longer to run your tests. How much longer? Noticeable. Too long? Up for debate. Honestly, with all the benefits it brings to the table, I am ok sacrificing a little bit of test runner speed.
Check out my project for using Jest + React + Browserify + Gulp on Github. It provides a starting point for new projects wanting to integrate Jest, React, Browserify, and Gulp. In the meantime, learn more about Jest and take it for a spin. You may be pleasantly surprised.