Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking node:crypto return value with Vitest

I tried following another related post on this topic with the creator's same outcome.

Since its post is dead I'd like to try again if someone has an idea on how to mock the node:crypto function or any builtin function.

My base case study is a simple randomUUID generator just to test that the mocking is working so I wanted to mock the randomUUID in order to return the value I wanted "123456789":

import { randomUUID } from "node:crypto";

export function getRandomUUID() :string {
  return randomUUID();
}

and I tried like in the above post the suggested solution:

 vi.mock("node:crypto", async () => {
      const actual =
        await vi.importActual<typeof import("node:crypto")>("node:crypto");
      return {
        ...actual,
        randomUUID: vi.fn(() => "123456789"),
      };
    });

The getRandomUUID return undefined in this case

I also tried a similar jest solution on this post

but vitest fails with an error about the import:

Error: [vitest] No "default" export is defined on the "node:crypto" mock. Did you forget to return it from "vi.mock"?
If you need to partially mock a module, you can use "importOriginal" helper inside:

vi.mock(import("node:crypto"), async (importOriginal) => {
  const actual = await importOriginal()
  return {
    ...actual,
    // your mocked methods
  }
})

so I tried this one as well with my mock method (the mock doesn't like the return type of randomUUID tho Type 'string' is not assignable to type '${string}-${string}-${string}-${string}-${string}')

    vi.mock(import("node:crypto"), async (importOriginal) => {
      const actual = await importOriginal();
      return {
        actual,
        // your mocked methods
        randomUUID: vi.fn(() => "123456789"),
      };
    });

and doesn't mock the actual method

like image 451
Alberto Avatar asked May 15 '26 16:05

Alberto


1 Answers

Maybe I'm missing what you're trying to do, but taking the example from the docs where they mock pg I end up with this:

main.js

import { randomUUID } from 'node:crypto'

export function getRandomUUID(): string {
  return randomUUID()
}

main.test.js

import { describe, expect, it, vi } from 'vitest'
import { getRandomUUID } from './main.js'

vi.mock('node:crypto', () => {
  return { randomUUID: vi.fn(() => '123456789') }
})

describe('main', () => {
  it('should be true', () => {
    expect(getRandomUUID()).toBe('123456789')
  })
})

Output:

 ✓ main.test.ts (1 test) 2ms
   ✓ main > should be true

 Test Files  1 passed (1)
      Tests  1 passed (1)
   Start at  10:38:42
   Duration  11ms
like image 122
shotor Avatar answered May 18 '26 05:05

shotor