Amused by Jest Unit Testing

03.04.20153 Min Read — In Programming

About a month ago, Pete (@ph1) and I had a conversation about Javascript testing frameworks and we agreed that there’s not one right answer. You don’t have to commit yourself to a magical tool for something as simple as testing, however, a battle of testing frameworks can definitely be had given that there are so many to choose from.

I talked a little bit about Jest and how it seemed to be beneficial in the fact that it takes care of auto-mocking dependencies. The reason I found this beneficial, or at least time saving, was from experience of having to write a lot of boilerplate code in order to mock dependencies with Angular unit testing. So, when you find a testing framework that promises to make test set-up sound easy, there’s no reason not to try it out.

So, try it out I did, and I dragged another friend, Dan (@dc_minutiae), along. Our goal was to do a deep dive into React.js, the Flux architecture, and best practices with testing so that we could TDD the design of a web application. In retrospect, maybe our undertaking was a lot to learn at once. One of the goals would be to keep track of a music playlist with files uploaded through the browser. We called our pet project Hyperflux out of our love for The Hype Machine.

We started out by looking for a boilerplate/scaffold that could fit our needs on Awesome React. One of the boiler-plates we chose had node-jsx as a dependency which allows you to require jsx from node. However, we quickly started running into problems when node-jsx appeared in any of the dependency trees for boiler-plates we wanted to try. This caused Jest’s auto-mocking to start losing its luster.

The discovery of node-jsx being a troublesome dependency was not an easy one. We discovered that the require.extensions global is being deprecated and no longer supported and this was causing issues off the bat. Running a test that did nothing was not even possible. The workflow for finding dependencies that cause problem with Jest was cumbersome. You can mark npm dependency paths to be un-mocked via configuration but it always seems like a treasure hunt to figure out which ones need to be un-mocked.

Dan and I were also dumbfounded with how slow our tests were running. Over the course of a couple days fighting configuration and writing a handful of tests, we started noticing our test “suite” was taking more than 10 seconds to complete. Wat.

After some reflection, we decided that using a boilerplate with a ton of dependencies we may or may not use was not the best choice. These could cause a lot of overhead with script pre-processing if you’re JSX-transforming non-JSX files in addition to increasing the breadth and depth of the dependency tree for Jest’s HasteModuleLoader to handle.

Our Jest config started getting complicated as time went on and it was clear that we had a lot of dev dependencies to be cognizant of to un-mock.

var jestConfig = {
  rootDir: ".",
  testPathDirs: ["<rootDir>/src/__tests__/client/"],
  scriptPreprocessor: "<rootDir>/node_modules/babel-jest",
  testFileExtensions: ["es6", "js"],
  moduleFileExtensions: ["js", "json", "es6"],
  unmockedModulePathPatterns: [
    "node_modules/react",
    "node_modules/object-assign",
    "node_modules/express",
    "node_modules/supertest",
    "node_modules/chai",
    "node_modules/chai-http",
    "node_modules/multer"
  ]
};

SuperTest was one dependency that couldn’t be used because of Jest’s version of Jasmine does not support the .end() callback that SuperTest needs in order to make assertions. Without it, our tests had no indication of whether they were done or not.

😕

So it’s clear, sometimes the tools we pick up to use for a job need a little more understanding before they solve our problems. In this case, we struggled more than we had hoped and my first impression of Jest is not the greatest. However, I’m always open to trying out new things but in this case, it may have been better to choose boring technology in the Javascript space so that we could get to the meat of learning React + Flux.

© 2018 by Pamela Ocampo. All rights reserved.
GitHub
Last build: 15.06.2022