Search code examples
typescriptvitestbun

Typescript complains that vitests onTestFailed function is undefined despite of importing it


I'm trying to add additional information to failing tests in a bigger typescript project.

I found the onTestFailed hook that registers a callback function to a test. So for a quick test, I followed the example in the documentation.

Here is my small example

import { expect, onTestFailed, test } from "vitest"

function addContextReport(context: Record<string, string>) {
  onTestFailed(() => {
    console.error("test Failed. Context:")
    for (const key in context) console.error(`${key}: ${context[key]}`)
  })
}

test("a test", () => {
  const context = { seed: "random" }
  addContextReport(context)
  expect(2 + 2).toBe(3)
})

When I run this code two things happen:

  1. I get the onTestFailed is undefined pointing to the line in the addContextReport function, not the import. The exact error is
    TypeError: onTestFailed is not a function. (In 'onTestFailed(() => {
      console.error("test Failed. Context:");
      for (const key in context)
        console.error(`${key}: ${context[key]}`);
    })', 'onTestFailed' is undefined)
    
  2. The test can still be executed and produces the expected result.

I found this question/answer and added "types": ["vitest/globals"] to my tsconfig.json file but it had no effect on the issue.

Since the code seems to work, I thought this might be an issue with typescript getting confused for some reason. So I tried to overwrite the type

const testFn: (_:any) => void = onTestFailed

However, I then got the same error as before on this line.

So in total it looks like the code is ok and for some reason typescript complains. I hope someone can point me in the right direction where to look for a solution.

FYI: I'm using bun 1.1.38, vitest 2.1.8, typescript 5.7.2

UPDATE: I executed the tests using bun test.


Solution

  • So digging shows, that bun injects their own Jest compatible testing framework. So even though I import explicitly vitest, bun:test seems to be loaded. Further, onTestFailed seems to be no Jest function and thus also not part of buns test framework.

    So one option is to define

    "scripts": {
        "test": "which vitest && vitest run --bail 1 --reporter=verbose",
    }
    

    In package.json and use bun run test instead of bun test. However, bun test will not work for any test using onTestFailed.