# Unit Testing jscodeshift Transformations

jscodeshift comes with a simple utility to allow easy unit testing with Jest (opens new window), without having to write a lot of boilerplate code. This utility makes some assumptions in order to reduce the amount of configuration required:

  • The test is located in a subdirectory under the directory the transform itself is located in (eg. __tests__)
  • Test fixtures are located in a __testfixtures__ directory

This results in a directory structure like this:

/MyTransform.js
/__tests__/MyTransform-test.js
/__testfixtures__/MyTransform.input.js
/__testfixtures__/MyTransform.output.js
1
2
3
4

A simple example of unit tests is bundled in the sample directory (opens new window).

The testUtils module (opens new window) exposes a number of useful helpers for unit testing.

# defineTest

Defines a Jest/Jasmine test for a jscodeshift transform which depends on fixtures

jest.autoMockOff();
const defineTest = require('jscodeshift/dist/testUtils').defineTest;
defineTest(__dirname, 'MyTransform');
1
2
3

An alternate fixture filename can be provided as the fourth argument to defineTest. This also means that multiple test fixtures can be provided:

defineTest(__dirname, 'MyTransform', null, 'FirstFixture');
defineTest(__dirname, 'MyTransform', null, 'SecondFixture');
1
2

This will run two tests:

  • __testfixtures__/FirstFixture.input.js
  • __testfixtures__/SecondFixture.input.js

See the example in folder crguezl/hello-jscodeshift/prefix-functions (opens new window) in the master branch

# defineInlineTest

Defines a Jest/Jasmine test suite for a jscodeshift transform which accepts inline values

This is a more flexible alternative to defineTest, as this allows to also provide options to your transform

const defineInlineTest = require('jscodeshift/dist/testUtils').defineInlineTest;
const transform = require('../myTransform');
const transformOptions = {};
defineInlineTest(transform, transformOptions, 'input', 'expected output', 'test name (optional)');
1
2
3
4

# defineSnapshotTest

Similar to defineInlineTest but instead of requiring an output value, it uses Jest's toMatchSnapshot()

const defineSnapshotTest = require('jscodeshift/dist/testUtils').defineSnapshotTest;
const transform = require('../myTransform');
const transformOptions = {};
defineSnapshotTest(transform, transformOptions, 'input', 'test name (optional)');
1
2
3
4

For more information on snapshots, check out Jest's docs (opens new window)

# defineSnapshotTestFromFixture

Similar to defineSnapshotTest but will load the file using same file-directory defaults as defineTest

const defineSnapshotTestDefault = require('jscodeshift/dist/testUtils').defineSnapshotTestDefault;
const transform = require('../myTransform');
const transformOptions = {};
defineSnapshotTestFromFixture(__dirname, transform, transformOptions, 'FirstFixture', 'test name (optional)');
1
2
3
4

# applyTransform

Executes your transform using the options and the input given and returns the result. This function is used internally by the other helpers, but it can prove useful in other cases.

const applyTransform = require('jscodeshift/dist/testUtils').applyTransform;
const transform = require('../myTransform');
const transformOptions = {};
const output = applyTransform(transform, transformOptions, 'input');
1
2
3
4

# ES modules

If you're authoring your transforms and tests using ES modules, make sure to import the transform's parser (if specified) in your tests:

// MyTransform.js
export const parser = 'flow'
export default function MyTransform(fileInfo, api) {
  // ...
}
1
2
3
4
5
// __tests__/MyTransform-test.js
import { defineInlineTest } from 'jscodeshift/dist/testUtils
import * as transform from '../MyTransform

console.log(transform.parser) // 'flow'

defineInlineTest(transform, /* ... */)
1
2
3
4
5
6
7

# References

See the section references about AST transformations

The tutorial Writing Javascript Codemods and Understanding AST Easily (opens new window) in Arminas Katilius Personal Blog, makes special emphasis in testing with jscodeshift.

Last Updated: 3 months ago