DRY up your Jasmine specs with a subject

Henric Trotzig
2 min readNov 24, 2014

--

Have you ever been frustrated by how repetitive your Jasmine specs become? Do you write a spec to test a certain outcome in one context and find yourself copy-pasting the same setup in another?

At Brigade, we use Jasmine extensively to test our front-end JavaScript code. Lately, we’ve started to use a new pattern that takes inspiration from RSpec’s subject and let. Here’s an example spec for a Button React component:

This example uses both JSX and ES6 syntax. Those aren’t required for the pattern of course, but are great tools for making the daily JavaScript grind more comfortable. There are also a few custom matchers here, like toHaveIcon and toHaveText. Custom matchers are great for making your specs better.

First, we set up the main subject under test. In the example above, it’s a rendered version of the Button component. We make it a function, so that we can lazily execute it at the right time (which is after all the params have been finalized, in this case this.props). Each describe block is then started with a beforeEach call where params are initialized (this.props in the example) for the thing/things that we are going to test in that block. If we nest describe blocks, we can even patch existing params initialized further up in the hierarchy. This is what we do in the “and an `icon` prop” block.

Exactly how much DRYer will using this pattern make your specs? It depends on the thing that you’re testing of course. It doesn’t make files much smaller. It does reduce a bit of boilerplate, but not much. The most important part isn’t how much it improves one spec file. The gold here is how this pattern affects an entire suite of specs. It provides a simple, common structure: all specs have a subject, all describe blocks alter params used by the subject, and all it blocks use the subject.

This is what the spec used to look like:

The same Button spec without using the subject pattern.

You could argue that another three lines of code isn’t too bad. And yes, there are other ways to DRY up this particular spec without using the subject pattern, like introducing a method to render the component. Or combining expects in a single it-block (that’s an anti-pattern though). However, the subject pattern really shines in more complicated specs, and when it is used consistently across all your specs.

Making it even better

We’ve been exploring taking this pattern a step further by expanding the DSL that Jasmine provides. Instead of putting subject in a beforeEach block, we could have a subject function that does that for us. And instead of specifying params in a beforeEach, we could introduce a function called let. This would turn the above example into the following:

Idea for extending the Jasmine DSL with subject and lets.

What do you think? Tweet me @henrictrotzig with feedback!

--

--