oxc-project/oxc · warning · OxcDiagnostic
Unexpected conditional expect
Error message
Unexpected conditional expect
What it means
Diagnostic from the oxlint rule `jest/no-conditional-expect` (shared with vitest) in crates/oxc_linter/src/rules/shared/jest_vitest/no_conditional_expect.rs:16. Jest decides pass/fail by thrown errors, so an expect() that only runs on some branches can let a test pass without its assertion ever executing. The rule reports any expect call inside conditional control flow.
Source
Thrown at crates/oxc_linter/src/rules/shared/jest_vitest/no_conditional_expect.rs:16
use oxc_ast::AstKind;
use oxc_diagnostics::OxcDiagnostic;
use oxc_semantic::{AstNode, NodeId};
use oxc_span::Span;
use rustc_hash::FxHashSet;
use crate::{
context::LintContext,
utils::{
JestFnKind, JestGeneralFnKind, PossibleJestNode, is_type_of_jest_fn_call,
parse_expect_jest_fn_call,
},
};
fn no_conditional_expect_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Unexpected conditional expect")
.with_help("Avoid calling `expect` conditionally")
.with_label(span)
}
pub const DOCUMENTATION: &str = r"### What it does
This rule prevents the use of `expect` in conditional blocks, such as `if` and `catch`.
This includes using `expect` in callbacks to functions named `catch`, which are assumed to be promises.
### Why is this bad?
Jest only considers a test to have failed if it throws an error, meaning if calls to
assertion functions like `expect` occur in conditional code such as a `catch` statement,
tests can end up passing but not actually test anything. Additionally, conditionals
tend to make tests more brittle and complex, as they increase the amount of mental
thinking needed to understand what is actually being tested.
### ExamplesView on GitHub (pinned to e1e7af627c)
Solutions
- Move the assertion out of the branch: assert on the conditional value itself, e.g. expect(result ?? null).toBe(x)
- Replace try/catch assertion patterns with dedicated matchers: await expect(promise).rejects.toThrow('boom')
- If the condition selects data, compute the expected value first and keep expect() unconditional
Example fix
// before
try {
const r = await load();
if (r) expect(r.id).toBe(1);
} catch (e) {
expect(e).toBeUndefined();
}
// after
await expect(load()).resolves.toMatchObject({ id: 1 }); Defensive patterns
Strategy: validation
Validate before calling
npx oxlint -c .oxlintrc.json tests/ # jest/no-conditional-expect flags expect inside if/catch/ternary
Prevention
- Always make expect() the outermost async assertion: await expect(p).resolves/.rejects
- Compute conditional values before asserting, never assert inside a branch
- Never put assertions inside .catch callbacks
When it happens
Trigger: expect() inside an `if` body, a `catch` block, a ternary or switch branch, or inside a callback passed to a function named `catch` (assumed to be a promise .catch). The rule walks ancestors of each expect call node (found via is_type_of_jest_fn_call with JestFnKind::Expect) looking for those conditional contexts.
Common situations: Guards like `if (result) expect(result).toBe(x)`; assertions inside try/catch where the catch swallows failures; expect inside .catch(err => expect(err).toBeFalsy()); porting tests from frameworks where conditional assertions were idiomatic.
Related errors
- Require a message for {matcher_name:?}.
- `expect` must be inside of a test block.
- Suggest using `toBeCalledWith()` or `toHaveBeenCalledWith()`
- Suggest using the built-in equality matchers.
- `{prefix}.hasAssertions` expects no arguments.
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/53b081846d2b2e7a.
Report an issue: GitHub.