Interpolated Inline Snapshot
ID |
javascript.inline_snapshot_interpolation |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
JavaScript |
Tags |
reliability, snapshot, testing |
Description
Reports a toMatchInlineSnapshot or toThrowErrorMatchingInlineSnapshot whose expected value is a template literal carrying a substitution.
An inline snapshot is not an ordinary argument: the framework owns that literal and rewrites it in place whenever the snapshot is updated, so it has to be a constant the tool can read and replace.
A template literal with no substitution is the shape the frameworks write themselves and is never reported; nor is an empty argument list, which is how an inline snapshot is first written before the framework fills it in.
Rationale
// Bad
expect(renderReceipt(cart)).toMatchInlineSnapshot(`Total: ${cart.total}`);
-
The assertion no longer states what the output is. It compares the output against an expression usually derived from the same code under test, so the test agrees with itself and would pass on a regression.
-
The update pass overwrites the expression with the literal text of the current output, silently deleting the code the author wrote inside the braces.
-
Reviewers reading the file cannot tell what the expected value is without running it, which removes the only advantage an inline snapshot has over a stored one.
-
Because the interpolated value changes with the fixture, the snapshot never stabilises and the churn is mistaken for normal snapshot noise.
Remediation
State the expected output as a constant, and assert derived values with an ordinary matcher.
// Good
expect(renderReceipt(cart)).toMatchInlineSnapshot(`Total: 42`);
expect(renderReceipt(cart)).toContain(`Total: ${cart.total}`);