oxc-project/oxc · warning · OxcDiagnostic
`expect` must be inside of a test block.
Error message
`expect` must be inside of a test block.
What it means
This is the oxlint `no-standalone-expect` rule (jest/vitest plugin), ported from eslint-plugin-jest. It fires when an `expect()` assertion call is made outside of any `test`/`it` block — for example directly in the module body or inside a `describe` callback. Such assertions are never executed by the test runner (or run at collection time), so they silently give false confidence in coverage. `expect` inside plain function declarations or variable-assigned helpers is intentionally allowed, and `expect.assertions()`/`expect.hasAssertions()` member calls are skipped because they legitimately run outside tests.
Source
Thrown at crates/oxc_linter/src/rules/shared/jest_vitest/no_standalone_expect.rs:23
use oxc_ast::AstKind;
use oxc_diagnostics::OxcDiagnostic;
use oxc_semantic::NodeId;
use oxc_span::Span;
use oxc_str::CompactStr;
use crate::{
AstNode,
context::LintContext,
rule::DefaultRuleConfig,
utils::{
JestFnKind, JestGeneralFnKind, KnownMemberExpressionParentKind, ParsedExpectFnCall,
PossibleJestNode, collect_possible_jest_call_node, get_node_name,
parse_expect_jest_fn_call, parse_general_jest_fn_call,
},
};
fn no_standalone_expect_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("`expect` must be inside of a test block.")
.with_help("Did you forget to wrap `expect` in a `test` or `it` block?")
.with_label(span)
}
pub const DOCUMENTATION: &str = r"### What it does
Prevents `expect` statements outside of a `test` or `it` block. An `expect`
within a helper function (but outside of a `test` or `it` block) will not
trigger this rule.
Statements like `expect.hasAssertions()` will NOT trigger this rule since these
calls will execute if they are not in a test block.
### Why is this bad?
`expect` statements outside of test blocks will not be executed by the Jest
test runner, which means they won't actually test anything. This can lead to
false confidence in test coverage and may hide bugs that would otherwise beView on GitHub (pinned to e1e7af627c)
Solutions
- Wrap the assertion in a `test(...)` or `it(...)` block.
- If the assertion sits in a custom test-wrapper function, add that function name to the rule's `additionalTestBlockFunctions` option in .oxlintrc.json.
- If the code is shared assertion logic, move it into a named helper function (function declaration or `const helper = () => ...`) and call it from inside tests — those are exempt by design.
- Delete the assertion if it is leftover dead code from a refactor.
Example fix
// before
describe('math', () => {
expect(1 + 1).toBe(2);
});
// after
describe('math', () => {
it('adds numbers', () => {
expect(1 + 1).toBe(2);
});
}); Defensive patterns
Strategy: validation
Validate before calling
// .oxlintrc.json
{
"plugins": ["jest"],
"rules": {
"jest/no-standalone-expect": "error",
"jest/no-standalone-expect": ["error", { "additionalTestBlockFunctions": ["itEachPlatform"] }]
}
}
# preflight before commit
npx oxlint tests/ Prevention
- Always author assertions inside an it/test callback; treat describe bodies as declaration-only zones.
- Register every custom test wrapper in additionalTestBlockFunctions when you introduce it.
- Run oxlint in a pre-commit hook or CI gate so a stray expect fails the build, not code review.
When it happens
Trigger: A `parse_expect_jest_fn_call`-recognized expect call whose enclosing function chain never terminates at a test block: expect() at the top level of a file, or `describe('x', () => { expect(1).toBe(1); })` with no `it` wrapper. Also fires when a custom test wrapper (e.g. `testEachPlatform('x', () => {...})`) is used but is not listed in the rule's `additionalTestBlockFunctions` config array, so the linter cannot recognize it as a test block.
Common situations: Refactoring that hoists an assertion out of a test callback; using an in-house wrapper around `test`/`it` (custom framework, e.g. `itEach`, `testConcurrent`) that the linter does not know; migrating a codebase to oxlint where the previous linter had the wrapper names configured; writing sanity checks in a `describe` body assuming describe callbacks run per-test.
Related errors
- Suggest using `toBeCalledWith()` or `toHaveBeenCalledWith()`
- Suggest using the built-in equality matchers.
- `{prefix}.hasAssertions` expects no arguments.
- `{prefix}.assertions` expects a single argument of type numb
- This argument should be a number.
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/9de2529acafe1dd8.
Report an issue: GitHub.