Jest Theories
jest-theories is a utility library for the Jest testing framework that enables data-driven test cases, inspired by concepts from XUnit and Jasmine Theories. It allows developers to write a single test function and execute it multiple times with varying inputs, known as 'theories.' This significantly reduces boilerplate and improves test maintainability by centralizing test logic while parameterizing data. The current stable version is 1.5.1, and its release cadence is typically driven by community contributions and specific feature or bug fix requirements, rather than a fixed schedule, indicating a maintenance-focused approach given its last publish date. A key differentiator is its use of `string-format` for flexible test naming, including the ability to use theory properties, `$idx` (index), and `$no` (number) within the test description string, or even provide a custom function for dynamic naming. It seamlessly integrates with Jest's `describe` and `test` structure, shipping with TypeScript types for enhanced developer experience.
Common errors
-
ReferenceError: theoretically is not defined
cause The `theoretically` function was not imported from 'jest-theories' in the test file.fixAdd `import theoretically from 'jest-theories';` at the top of your test file to make the function available. -
TypeError: Cannot read properties of undefined (reading 'input')
cause The `theory` object passed to the test callback is missing the expected property (e.g., 'input'), or the `theories` array is malformed, leading to an undefined access.fixVerify that your `theories` array contains objects with the correct property names, and that you are accessing them accurately (e.g., `theory.input`). Inspect the `theory` object using `console.log(theory)` inside the test callback. -
The first argument must be a string or a function.
cause The first argument provided to `theoretically` was neither a string for the test name template nor a function for dynamic naming. Often, the `theories` array is mistakenly passed as the first argument.fixEnsure the first argument is either a string (your test name template, e.g., `'the number {input}...'`) or a function that returns the test name, and the second argument is your array of theory objects.
Warnings
- gotcha Carefully review test name formatting strings. The library uses `string-format` syntax, which expects placeholders like `{propertyName}`. Mismatched property names or incorrect syntax will result in unformatted test names or errors.
- gotcha Using a very large number of theories (e.g., hundreds or thousands) in a single `theoretically` block can significantly increase test execution time and memory consumption, potentially impacting CI/CD performance.
- gotcha The `theory` object passed to the test callback is specific to each iteration. Variables declared outside the callback but intended to be part of the test data should be explicitly included in the theory object.
Install
-
npm install jest-theories -
yarn add jest-theories -
pnpm add jest-theories
Imports
- theoretically
const theoretically = require('jest-theories')import theoretically from 'jest-theories'
Quickstart
import theoretically from 'jest-theories';
// Mock function for demonstration purposes
const NumberToLongString = (num: number): string => {
if (num === 100) return 'One hundred';
if (num === 1000) return 'One thousand';
if (num === 10000) return 'Ten thousand';
if (num === 100000) return 'One hundred thousand';
return 'Unknown';
};
describe('NumberToLongString conversion', () => {
const theories = [
{ input: 100, expected: 'One hundred' },
{ input: 1000, expected: 'One thousand' },
{ input: 10000, expected: 'Ten thousand' },
{ input: 100000, expected: 'One hundred thousand' }
];
theoretically('the number {input} is correctly translated to string', theories, theory => {
const output = NumberToLongString(theory.input);
expect(output).toBe(theory.expected);
});
});