Skip to content

test: fix shared mock state and improve test isolation#2023

Open
SHUBHANSHU602 wants to merge 1 commit intoasyncapi:masterfrom
SHUBHANSHU602:fix-isolation
Open

test: fix shared mock state and improve test isolation#2023
SHUBHANSHU602 wants to merge 1 commit intoasyncapi:masterfrom
SHUBHANSHU602:fix-isolation

Conversation

@SHUBHANSHU602
Copy link
Copy Markdown
Contributor

@SHUBHANSHU602 SHUBHANSHU602 commented Mar 5, 2026

Description

This PR fixes test isolation issues in apps/generator/test/generator.test.js.

Several tests mutate shared state in the mocked utils module (such as __files, __contentOfFetchedFile, __isFileSystemPathValue, and __getTemplateDetails). Since the mock is loaded once at the module level, these mutations persisted across tests and could lead to unintended side effects between test cases.

Changes

  • Added a beforeEach block to reset mutable state in the utils mock before every test.
  • Cleared Jest mock call history using jest.clearAllMocks() to ensure each test starts with a clean state.
  • Replaced setTimeout-based assertions with deterministic expectations to avoid async assertions that Jest does not wait for.
  • Fixed minor lint issues (such as removing a useless path segment and adding missing trailing commas).

##Result

  • Prevents shared mock state from leaking between tests.
  • Improves reliability and determinism of the test suite.
  • Ensures tests remain independent and CI-safe.
Screenshot 2026-03-05 161145

**Resolves #1946

Summary by CodeRabbit

  • Tests
    • Improved test execution reliability and efficiency through enhanced mock setup and refactored assertion patterns for more consistent behavior.

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 5, 2026

⚠️ No Changeset found

Latest commit: e888389

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@asyncapi-bot
Copy link
Copy Markdown
Contributor

What reviewer looks at during PR review

The following are ideal points maintainers look for during review. Reviewing these points yourself beforehand can help streamline the review process and reduce time to merge.

  1. PR Title: Use a concise title that follows our Conventional Commits guidelines and clearly summarizes the change using imperative mood (it means spoken or written as if giving a command or instruction, like "add new helper for listing operations")

    Note - In Generator, prepend feat: or fix: in PR title only when PATCH/MINOR release must be triggered.

  2. PR Description: Clearly explain the issue being solved, summarize the changes made, and mention the related issue.

    Note - In Generator, we use Maintainers Work board to track progress. Ensure the PR Description includes Resolves #<issue-number> or Fixes #<issue-number> this will automatically close the linked issue when the PR is merged and helps automate the maintainers workflow.

  3. Documentation: Update the relevant Generator documentation to accurately reflect the changes introduced in the PR, ensuring users and contributors have up-to-date guidance.

  4. Comments and JSDoc: Write clear and consistent JSDoc comments for functions, including parameter types, return values, and error conditions, so others can easily understand and use the code.

  5. DRY Code: Ensure the code follows the Don't Repeat Yourself principle. Look out for duplicate logic that can be reused.

  6. Test Coverage: Ensure the new code is well-tested with meaningful test cases that pass consistently and cover all relevant edge cases.

  7. Commit History: Contributors should avoid force-pushing as much as possible. It makes it harder to track incremental changes and review the latest updates.

  8. Template Design Principles Alignment: While reviewing template-related changes in the packages/ directory, ensure they align with the Assumptions and Principles. If any principle feels outdated or no longer applicable, start a discussion these principles are meant to evolve with the project.

  9. Reduce Scope When Needed: If an issue or PR feels too large or complex, consider splitting it and creating follow-up issues. Smaller, focused PRs are easier to review and merge.

  10. Bot Comments: As reviewers, check that contributors have appropriately addressed comments or suggestions made by automated bots. If there are bot comments the reviewer disagrees with, react to them or mark them as resolved, so the review history remains clear and accurate.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 5, 2026

📝 Walkthrough

Walkthrough

Added a beforeEach hook to reset mocks and reinitialize utilities before each test. Introduced a mock for @asyncapi/parser with convertToOldAPI as a passthrough. Replaced asynchronous setTimeout-based assertions with direct, immediate assertions in installation and template resolution tests to eliminate event-loop timing dependencies.

Changes

Cohort / File(s) Summary
Test Mock and Assertion Refactoring
apps/generator/test/generator.test.js
Added beforeEach hook to reset mocks and reinitialize utils properties for test isolation. Introduced mock for @asyncapi/parser with convertToOldAPI passthrough. Replaced setTimeout-based async assertions with direct assertions for installation path and template resolution tests, removing event-loop timing dependencies.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'test: fix shared mock state and improve test isolation' follows Conventional Commits guidelines with 'test:' prefix and uses imperative mood, clearly summarizing the main changes.
Linked Issues check ✅ Passed The PR directly addresses all coding objectives from issue #1946: resets mock state via beforeEach block, clears mock call history, replaces setTimeout assertions with deterministic expectations, and eliminates shared mock state leakage.
Out of Scope Changes check ✅ Passed All changes are scoped to test isolation improvements: mock state reset, jest.clearAllMocks() calls, and replacing setTimeout-based assertions. Minor lint fixes are within scope as supporting improvements.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Mar 5, 2026

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/generator/test/generator.test.js (1)

378-383: ⚠️ Potential issue | 🟠 Major

works with an npm package is missing its cache-hit precondition.

Line 382 asserts no install happened, but this test never seeds utils.__getTemplateDetails. With Line 28 resetting it to undefined, the intended “already installed” branch is not actually arranged.

💡 Proposed fix
 it('works with an npm package', async () => {
   utils.__isFileSystemPathValue = false;
+  utils.__getTemplateDetails = {
+    pkgPath: '/path/to/template/nameOfTestTemplate',
+    name: 'nameOfTestTemplate',
+    version: '1.0.0',
+  };
   const gen = new Generator('nameOfTestTemplate', __dirname);
   await gen.installTemplate();
   expect(arboristMock.reify).not.toHaveBeenCalled();
 });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/generator/test/generator.test.js` around lines 378 - 383, The test
"works with an npm package" sets utils.__isFileSystemPathValue but never primes
the cache condition (utils.__getTemplateDetails) so Generator.installTemplate
takes the install path; seed utils.__getTemplateDetails to represent an
already-resolved template before calling new Generator/installTemplate (e.g.,
set utils.__getTemplateDetails to the same template detail object the real code
checks) so the code follows the cache-hit branch and arboristMock.reify remains
uncalled; update the test to set utils.__getTemplateDetails appropriately and
restore/reset it after the test if other tests rely on the undefined default.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@apps/generator/test/generator.test.js`:
- Around line 378-383: The test "works with an npm package" sets
utils.__isFileSystemPathValue but never primes the cache condition
(utils.__getTemplateDetails) so Generator.installTemplate takes the install
path; seed utils.__getTemplateDetails to represent an already-resolved template
before calling new Generator/installTemplate (e.g., set
utils.__getTemplateDetails to the same template detail object the real code
checks) so the code follows the cache-hit branch and arboristMock.reify remains
uncalled; update the test to set utils.__getTemplateDetails appropriately and
restore/reset it after the test if other tests rely on the undefined default.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5bcef845-32f4-4309-a47a-ba1c5db44a84

📥 Commits

Reviewing files that changed from the base of the PR and between b76523e and e888389.

📒 Files selected for processing (1)
  • apps/generator/test/generator.test.js

Comment on lines +2 to +4
jest.mock('@asyncapi/parser', () => ({
convertToOldAPI: jest.fn((doc) => doc),
}));
Copy link
Copy Markdown
Member

@Adi-204 Adi-204 Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why we need this change?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Adi-204 I know it seems like voilating the scope, BUT

While fixing the isolation issue, the tests started reaching the actual parser conversion logic inside lib/parser.js. Previously, because of shared mutable state in the mocks and the way tests were structured, this code path was not always executed consistently.

When the tests began running in a properly isolated state, they attempted to call convertToOldAPI from @asyncapi/parser. However, newer versions of @asyncapi/parser no longer expose this function, which results in the runtime error:

TypeError: convertToOldAPI is not a function

Since the goal of this test suite is to verify the behavior of the Generator class rather than the internals of the parser library, I mocked convertToOldAPI to return the document unchanged. This keeps the tests focused on generator behavior while avoiding failures caused by parser implementation details.

If you prefer, I can also adjust the tests to avoid mocking the parser and instead rely on the actual parser behavior.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @SHUBHANSHU602, I tried removing the mock locally and ran the tests, and they all passed without any TypeError. So I’m not able to reproduce the issue on my end. Because of that, I’m not sure how the tests are reaching the parser conversion logic in lib/parser.js. Could you share a bit more detail on how you observed this behavior? That would help me better understand the issue and verify it properly.

Copy link
Copy Markdown
Contributor Author

@SHUBHANSHU602 SHUBHANSHU602 Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Adi-204 I think I have made the things quite complicated , I will rewrite all the things , to keep the things simple and to avoid scope voilation and confusion.

@derberg derberg moved this to In Progress in Maintainers work Mar 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

[BUG] :-Tests in generator.test.js rely on shared mutable mocks and non-awaited async assertions, breaking isolation

4 participants