help icon indicating copy to clipboard operation
help copied to clipboard

[node:test] How to mocking function exported with named export

Open Lycolia opened this issue 5 months ago • 2 comments

Details

I'm trying to mock a function that has been exported using named export, but I'm not able to do it successfully. How can I mock it properly?

Any help would be greatly appreciated!

Expected Behavior

test passing

Actual Behavior

✖ failing tests:

✖ validateFoo (0.793581ms)
  TypeError: "The argument 'methodName' must be a method. Received undefined"
      at __node_internal_captureLargerStackTrace (node:internal/errors:490:5)
      at new NodeError (node:internal/errors:399:5)
      at MockTracker.method (node:internal/test_runner/mock:180:13)
      at TestContext.<anonymous> (/home/user/develop/path/to/src/hoge.spec.ts:8:12)
      at Test.runInAsyncScope (node:async_hooks:206:9)
      at Test.run (node:internal/test_runner/test:550:25)
      at Test.start (node:internal/test_runner/test:466:17)
      at node:internal/test_runner/test:788:71
      at node:internal/per_context/primordials:482:82
      at new Promise (<anonymous>)
      at new SafePromise (node:internal/per_context/primordials:450:29)
      at node:internal/per_context/primordials:482:9
      at Array.map (<anonymous>)
      at arrayToSafePromiseIterable (node:internal/per_context/primordials:479:5)
      at node:internal/per_context/primordials:496:21
      at new Promise (<anonymous>)
      at primordials.SafePromiseAll (node:internal/per_context/primordials:495:3)
      at Suite.run (node:internal/test_runner/test:788:23)
      at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
      at async startSubtest (node:internal/test_runner/harness:203:3)

✖ example (1.794746ms)
  [Error: 1 subtest failed
  ]

Node.js version

v20.0.0

Example code

Implementation Code

export const validateFoo = () => {
  console.log('foo');
};

export const hoge = () => {
  validateFoo();
};

Test Code

import { describe, it } from 'node:test';
import assert from 'node:assert';
import * as HogeObj from './hoge';
import { hoge } from './hoge';

describe('example', () => {
  it('validateFoo', (t) => {
    t.mock.method(HogeObj, 'validateFoo', () => {
      throw new Error('foo');
    });

    assert.throws(() => {
      hoge();
    }, Error);
  });
});

Operating system

Ubuntu 22.04.3 LTS

Scope

test

Module and version

  • node:test
  • node:assert

Lycolia avatar Jan 13 '24 17:01 Lycolia

I have the same problem, I looked at this issue and apparently the native node test does not have support for mocking modules https://github.com/nodejs/help/issues/4298

Molezinif avatar Mar 01 '24 16:03 Molezinif

Odd note, when I do:

import fs from 'node:fs'
import * as blah from './blah';

test('my test', (t) => {
  // this works
  t.mock.method(fs, 'writeFileSync', () => /* */);

  // this doesn't work
  t.mock.method(blah, 'someExport', () => /* */);
});

I'm guessing this is either because I'm using a loader (node --loader tsx mytest.test.ts), or the node:fs module is actually exporting an object, whereas blah.ts just has export function thing() {}.

In any case, I would also like to be able to mock exports from local files

mehulkar avatar Apr 12 '24 17:04 mehulkar