Skip to content

TestContext not passed to hooks in node:test - #26185

Closed
jeansouzak wants to merge 2 commits into
oven-sh:mainfrom
jeansouzak:fix/node-test-create-hook
Closed

TestContext not passed to hooks in node:test#26185
jeansouzak wants to merge 2 commits into
oven-sh:mainfrom
jeansouzak:fix/node-test-create-hook

Conversation

@jeansouzak

@jeansouzak jeansouzak commented Jan 17, 2026

Copy link
Copy Markdown

This PR fixes #26170

What does this PR do?

This PR fixes a bug where TestContext was not being passed to hook functions when using t.after(), t.afterEach(), t.before(), and t.beforeEach() in the node:test module.

The Problem

When registering hooks via TestContext methods (e.g., t.after((ctx) => ctx.diagnostic(...))), the hook function was not receiving the TestContext as a parameter, causing TypeError: undefined is not an object (evaluating 't.diagnostic') errors.

The Solution

The fix modifies the createHook() function to accept an optional TestContext parameter and pass it to the hook function when available. The changes include:

  1. Updated hook methods to pass this (the TestContext instance) to createHook():

    • TestContext.before()
    • TestContext.after()
    • TestContext.beforeEach()
    • TestContext.afterEach()
  2. Modified createHook() function to accept an optional context?: TestContext parameter and pass it to the hook function when calling it.

  3. Updated type definition for HookFn to accept an optional TestContext parameter: (ctx?: TestContext) => unknown | Promise<unknown>

  4. Maintained backward compatibility - hooks that don't expect a context parameter continue to work as before.

Example

Before (broken):

test('example test', async (t) => {
  t.after((t) => {
    t.diagnostic(`finished running ${t.name}`); // TypeError: t is undefined
  });
});

After (fixed):

test('example test', async (t) => {
  t.after((t) => {
    t.diagnostic(`finished running ${t.name}`); // Works correctly!
  });
});

How did you verify your code works?

  1. Created comprehensive tests in execution-test/test-context-hooks.test.ts that verify:

    • after() hook receives TestContext correctly
    • afterEach() hook receives TestContext correctly
    • Original bug case from issue report now works
    • Backward compatibility (hooks without context parameter still work)
    • Context properties are accessible in hooks
    • Multiple hooks with context work correctly
    • Async hooks with context work correctly
    • Context verification in various scenarios
  2. Verified the original bug is fixed:

    bun bd test ./execution-test/test.test.ts

    The test that previously failed with TypeError: undefined is not an object (evaluating 't.diagnostic') now passes successfully.

  3. Ran all new tests:

    bun bd test ./execution-test/test-context-hooks.test.ts

    All 8 tests pass, confirming that:

    • TestContext is correctly passed to hooks
    • All context properties (name, filePath, signal, assert) are accessible
    • Backward compatibility is maintained
    • Async hooks work correctly
  4. Tested with the original issue reproduction case:

    import { test } from 'node:test';
    
    test('example test', async (t) => {
      t.after((t) => t.diagnostic(`finished running ${t.name}`));
      console.log('Hello World');
    });

    This now works correctly, printing both "Hello World" and "finished running example test" as expected.

Changes Made

  • src/js/node/test.ts:
    • Modified TestContext.before(), after(), beforeEach(), and afterEach() to pass this to createHook()
    • Updated createHook() function signature to accept optional context?: TestContext parameter
    • Modified hook execution to pass context when available: result = context ? fn(context) : fn()
    • Updated HookFn type to accept optional TestContext parameter

Related Issue

#26170

@coderabbitai

coderabbitai Bot commented Jan 17, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

Modifies hook creation to accept and propagate TestContext through hook functions. Updates HookFn type signature to accept an optional TestContext parameter, allowing hooks to optionally receive test context during execution.

Changes

Cohort / File(s) Summary
Hook context propagation
src/js/node/test.ts
Updated createHook function signature to accept optional context?: TestContext as third parameter. Modified HookFn type from parameterless function to (ctx?: TestContext) => unknown | Promise<unknown>. Hook wrappers (before/after/beforeEach/afterEach) now pass this context when invoking createHook. Hook execution calls fn(context) when context is provided, otherwise falls back to fn().
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title directly and specifically summarizes the main change: fixing the bug where TestContext was not being passed to hooks in node:test.
Description check ✅ Passed The PR description comprehensively covers both required template sections with detailed problem statement, solution, examples, and verification steps.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@robobun

robobun commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

Thank you for this contribution!

This was fixed in #32631: invokeTestFn now passes the TestContext into hooks. See src/js/node/test.ts on current main.

Closing as already fixed. Thanks again for the investigation and patch!

@robobun robobun closed this Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

node:test argument t of test is undefined

2 participants