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.

### Examples

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Move the assertion out of the branch: assert on the conditional value itself, e.g. expect(result ?? null).toBe(x)
  2. Replace try/catch assertion patterns with dedicated matchers: await expect(promise).rejects.toThrow('boom')
  3. 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

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


AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20). Data as JSON: /api/errors/53b081846d2b2e7a. Report an issue: GitHub.