{"record":{"id":"53b081846d2b2e7a","repo":"oxc-project/oxc","slug":"unexpected-conditional-expect","errorCode":null,"errorMessage":"Unexpected conditional expect","messagePattern":"Unexpected conditional expect","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/shared/jest_vitest/no_conditional_expect.rs","lineNumber":16,"sourceCode":"use oxc_ast::AstKind;\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_semantic::{AstNode, NodeId};\nuse oxc_span::Span;\nuse rustc_hash::FxHashSet;\n\nuse crate::{\n    context::LintContext,\n    utils::{\n        JestFnKind, JestGeneralFnKind, PossibleJestNode, is_type_of_jest_fn_call,\n        parse_expect_jest_fn_call,\n    },\n};\n\nfn no_conditional_expect_diagnostic(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Unexpected conditional expect\")\n        .with_help(\"Avoid calling `expect` conditionally\")\n        .with_label(span)\n}\n\npub const DOCUMENTATION: &str = r\"### What it does\n\nThis rule prevents the use of `expect` in conditional blocks, such as `if` and `catch`.\nThis includes using `expect` in callbacks to functions named `catch`, which are assumed to be promises.\n\n### Why is this bad?\n\nJest only considers a test to have failed if it throws an error, meaning if calls to\nassertion functions like `expect` occur in conditional code such as a `catch` statement,\ntests can end up passing but not actually test anything. Additionally, conditionals\ntend to make tests more brittle and complex, as they increase the amount of mental\nthinking needed to understand what is actually being tested.\n\n### Examples","sourceCodeStart":1,"sourceCodeEnd":34,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/shared/jest_vitest/no_conditional_expect.rs#L1-L34","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\ntry {\n  const r = await load();\n  if (r) expect(r.id).toBe(1);\n} catch (e) {\n  expect(e).toBeUndefined();\n}\n\n// after\nawait expect(load()).resolves.toMatchObject({ id: 1 });","handlingStrategy":"validation","validationCode":"npx oxlint -c .oxlintrc.json tests/ # jest/no-conditional-expect flags expect inside if/catch/ternary","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["jest","vitest","oxlint","testing","assertions","control-flow"],"backgroundTag":"conditional-test-assertion","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}