{"record":{"id":"e529c1d76210c58b","repo":"oxc-project/oxc","slug":"unnecessary-async-function-wrapper","errorCode":null,"errorMessage":"Unnecessary async function wrapper","messagePattern":"Unnecessary async function wrapper","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/shared/jest_vitest/no_unneeded_async_expect_function.rs","lineNumber":14,"sourceCode":"use oxc_ast::{\n    AstKind,\n    ast::{Argument, Expression, Statement},\n};\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_span::Span;\n\nuse crate::{\n    context::LintContext,\n    utils::{ParsedJestFnCallNew, PossibleJestNode, parse_jest_fn_call},\n};\n\nfn no_unneeded_async_expect_function_diagnostic(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Unnecessary async function wrapper\")\n        .with_help(\"Remove the async wrapper and pass the promise directly to expect\")\n        .with_label(span)\n}\n\npub const DOCUMENTATION: &str = r\"### What it does\n\nDisallows unnecessary async function wrapper for expected promises.\n\n### Why is this bad?\n\nWhen the only statement inside an async wrapper is `await someCall()`,\nthe call should be passed directly to `expect` instead. This makes the\ntest code more concise and easier to read.\n\n### Examples\n\nExamples of **incorrect** code for this rule:\n```js","sourceCodeStart":1,"sourceCodeEnd":32,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/shared/jest_vitest/no_unneeded_async_expect_function.rs#L1-L32","documentation":"This is the oxlint `no-unneeded-async-expect-function` rule (jest/vitest plugin). Wrapping a call in an `async () => { await fn() }` arrow before passing it to `expect()` defeats the assertion: `expect` receives a function value, not the promise, so `.resolves`/`.rejects` matchers never observe the awaited result. The rule flags expect() calls whose single argument is an async function/arrow whose body is only an awaited call, and tells you to pass the call itself.","triggerScenarios":"`expect(async () => { await someCall(); })` — an Argument that is an async arrow/function expression whose body consists solely of an `await someCall()` expression (or a single `return await someCall()`), typically followed by `.resolves`/`.rejects` matchers.","commonSituations":"Developers learning promise matchers who 'make sure it is async' by wrapping; refactoring `await` out of a test body into the expect argument; TypeScript users adding the wrapper to satisfy a type expectation about the argument.","solutions":["Pass the call directly and use the resolves matcher: `await expect(someCall()).resolves.toBe(expected)`.","For rejection paths use `await expect(someCall()).rejects.toThrow()`.","If the wrapper contains more than one statement, unwrap only the awaited call and keep the rest in the test body."],"exampleFix":"// before\nit('resolves', () => {\n  expect(async () => { await Promise.resolve('value'); }).resolves.toBe('value');\n});\n\n// after\nit('resolves', async () => {\n  await expect(Promise.resolve('value')).resolves.toBe('value');\n});","handlingStrategy":"validation","validationCode":"// .oxlintrc.json\n{ \"rules\": { \"jest/no-unneeded-async-expect-function\": \"error\" } }\n\nnpx oxlint tests/","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Remember expect() takes a value or promise — never a function you want executed.","Use the pattern `await expect(call()).resolves|rejects.matcher` for all promise assertions.","Add the rule to CI so the silent no-op wrapper never lands."],"tags":["jest","vitest","oxlint","testing","async-await","promises","static-analysis"],"backgroundTag":"redundant-async-wrapper","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}