Jest is gaining momentum in the JS world, so let's see how to use it with Rails.

· Rails  · 3 min read

How to set up JavaScript testing for Rails 7 with Jest

Jest is gaining momentum in the JS world, so let's see how to use it with Rails.

Prerequisites for Ruby, Rails, and JS environment

Here are the tools I used for this tutorial.

$> ruby --version
=> 3.1.2
$> rails --version
=> 7.0.3.1
$> node --version
=> 18.6.0
$> yarn --version
=> 1.22.19

Create new Rails app - no JavaScript yet

$> rails new myapp && cd myapp

Now wait for a minute… okay ! you have now a fresh new default Rails app.

Add the bare minimum files

Create a controller as follow in app/controllers/welcome_controller.rb

# inside app/controllers/welcome_controller.rb
class WelcomeController < ApplicationController
end

Configure a default route in config/routes.rb as follow

# inside config/routes.rb
Rails.application.routes.draw do
  get "welcome/index"
  root to: "welcome#index"
end

Add a view inside app/views/welcome/index.html.erb

<!-- inside app/views/welcome/index.html.erb -->
<h1>
  Hello !
  <h1></h1>
</h1>

Add and use an ES6 module

Create an ES6 module by creating a new file under app/javascript/magicAdd.js

// inside app/javascript/magicAdd.js
const magicAdd = (a, b) => {
  return a + b;
};
export default magicAdd;

And reference this file from the main pack :

// inside app/javascript/packs/application.js

// You can left pre-existing JavaScript, that's ok :)

import magicAdd from './magicAdd.js';

let a = magicAdd(2, 4);

console.log(`From mainjs, magicAdd result is ${a}`);

Stop your local web server, and run

$/myapp> bin/rails server

If no error is shown, you can run the local web server :

$/myapp> bin/rails s

Now open your browser and check the browser’s console to see if everything works properly.

Create a test for the JavaScript module

Create a new file inside test/javascript/magicAdd.spec.js

// inside test/javascript/magicAdd.spec.js
import magicAdd from 'magicAdd.js';

describe('magicAdd', () => {
  test('add two numbers', () => {
    // given
    let result = 0;
    // when
    result = magicAdd(1, 3);
    // then
    expect(result).toEqual(4);
  });
});

Add JavaScript dependencies to run the unit test

We need now :

  • jest, which is our testing framework,
  • @babel/preset-env and babel-jest because of the use of ES6,
  • istanbul-reports to have a nice code coverage report.

So let’s run

$/myapp> yarn add --dev @babel/preset-env babel-jest jest istanbul-reports

Configure Jest

Open package.json, it should look like this :

{
  "devDependencies": {
    "@babel/preset-env": "^7.18.10",
    "babel-jest": "^28.1.3",
    "istanbul-reports": "^3.1.5",
    "jest": "^28.1.3"
  }
}

Add the following property to package.json, so that Jest will know which directories and file to watch, and which one to ignore :

{
   // all properties as above remain the same...
   "devDependencies": {
    "@babel/preset-env": "^7.18.10",
    "babel-jest": "^28.1.3",
    "istanbul-reports": "^3.1.5",
    "jest": "^28.1.3"
  },
   // add the following property to package.json
  "jest": {
    "testPathIgnorePatterns": [
      "node_modules/",
      "config/webpack/test.js",
      "vendor/bundle/ruby"
    ],
    "moduleDirectories": [
      "node_modules",
      "app/javascript"
    ],
    "collectCoverage": true,
    "coverageReporters": [
      "text",
      "html"
    ],
    "coverageDirectory": "coveragejs"
  }

Configure babel with your Rails app

Add the following code inside babel.config.js, at the root of your Rails project.

module.exports = {
  presets: ['@babel/preset-env'],
};

Launch tests

That’s the big moment.

Run

$/myapp> yarn jest

**yarn run v1.22.19**

**PASS** **test/javascript/****magicAdd.spec.js**

**magicAdd**

****  **add two numbers (2 ms)**



**-------------|---------|----------|---------|---------|-------------------**

**File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s**

**-------------|---------|----------|---------|---------|-------------------**

**All files** **|** **100** **|** **100** **|** **100** **|** **100** **|**

**magicAdd.js** **|** **100** **|** **100** **|** **100** **|** **100** **|**

**-------------|---------|----------|---------|---------|-------------------**

**Test Suites:** **1 passed****, 1 total**

**Tests:** **1 passed****, 1 total**

**Snapshots:** **0 total**

**Time:** **0.656 s**

**Ran all test suites.**

**✨  Done in 1.54s.**

And open coveragejs/index.html in your browser to get coverage.

Summary

Nothing complicated, but as often with npm projects, you have to take of dependencies and insert libs in the right order. Start from a simple example like this one to understand how things work, we hope it helped!

Share:
Back to Blog

Related Posts

View All Posts »
Rails 8 Hotwire, a tutorial

Rails 8 Hotwire, a tutorial

Rails 8 comes with Hotwire by default to handle frontend complexity. Here is a simple tutorial from scratch.

Ruby-on-Rails ERB vs HAML

Ruby-on-Rails ERB vs HAML

This is an opinionated article about ERB and HAML with Rails. Let's compare each other and pick a winner.