Skip to content

Comments

fix(unbound-method): ignore inline use of jest.mocked(...)#1862

Merged
G-Rath merged 8 commits intojest-community:mainfrom
eryue0220:fix/issue-1800
Dec 28, 2025
Merged

fix(unbound-method): ignore inline use of jest.mocked(...)#1862
G-Rath merged 8 commits intojest-community:mainfrom
eryue0220:fix/issue-1800

Conversation

@eryue0220
Copy link
Contributor

Fix: #1800

Copy link
Collaborator

@G-Rath G-Rath left a comment

Choose a reason for hiding this comment

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

at this point I feel like this is an overly complicated solution - have you looked into why our existing logic for handling jest.mocked isn't catching this case?

@eryue0220
Copy link
Contributor Author

at this point I feel like this is an overly complicated solution - have you looked into why our existing logic for handling jest.mocked isn't catching this case?

Sorry for the response, in this case the jest.mocked will be early returned in this if statement. A more easier way is to add condition that is lastLink !== 'mocked'. But I'm not sure this change is safe enough, so I tried a new way.

Copy link
Collaborator

@G-Rath G-Rath left a comment

Choose a reason for hiding this comment

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

I still would expect we can identify the call with parseJestFn, but what you've got it a lot simpler than what you had before and finding the right node to parse can be a pain at times, so I'm happy to go with this once you've simplified it a bit more with the isSupportedAccessor change

// Check if the call is jest.mocked() by examining the callee
if (
parentCall.callee.type === AST_NODE_TYPES.MemberExpression &&
isSupportedAccessor(parentCall.callee.object) &&
Copy link
Collaborator

Choose a reason for hiding this comment

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

isSupportedAccessor takes an optional value as its second param for just these situations - so rather than having to do the work twice, you can just do isSupportedAccessor(..., 'jest')

that in turn means you should be able to refactor this all to be a return

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated.

Comment on lines 107 to 118

// Also try using parseJestFnCall as a fallback
// const jestFnCall = parseJestFnCall(
// findTopMostCallExpression(parentCall),
// context,
// );

// return (
// jestFnCall?.type === 'jest' &&
// jestFnCall.members.length >= 1 &&
// isIdentifier(jestFnCall.members[0], 'mocked')
// );
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
// Also try using parseJestFnCall as a fallback
// const jestFnCall = parseJestFnCall(
// findTopMostCallExpression(parentCall),
// context,
// );
// return (
// jestFnCall?.type === 'jest' &&
// jestFnCall.members.length >= 1 &&
// isIdentifier(jestFnCall.members[0], 'mocked')
// );

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated.

node: TSESTree.MemberExpression,
): boolean => {
// Check if the immediate parent is a CallExpression
if (node.parent?.type !== AST_NODE_TYPES.CallExpression) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

this is the opposite of the check we do later on, so ideally we can merge the two but that might be messy due to the optional chaining and require an else which I try to avoid so not too fussed to keep it like this for now

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agreed. I tried another way, but it still failed.

@eryue0220
Copy link
Contributor Author

As mentioned before, the parseJestFn failed due to this [condition check](https://github.com/jest-community/eslint-plugin-jest/blob/main/src/rules/utils/parseJestFnCall.ts#L341], jest.mocked(service.method).mock.calls[0][0] was parsed as MemberExpression, then it failed.

@G-Rath G-Rath changed the title fix(unbound-method): fix issue 1800 fix(unbound-method): ignore inline use of jest.mocked(...) Dec 28, 2025
@G-Rath G-Rath added the bug label Dec 28, 2025
@G-Rath G-Rath merged commit 3a50b97 into jest-community:main Dec 28, 2025
20 checks passed
github-actions bot pushed a commit that referenced this pull request Dec 29, 2025
## [29.11.1](v29.11.0...v29.11.1) (2025-12-29)

### Bug Fixes

* **unbound-method:** ignore inline use of `jest.mocked(...)` ([#1862](#1862)) ([3a50b97](3a50b97))
@github-actions
Copy link

🎉 This PR is included in version 29.11.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[unbound-method]: should ignore accessing jest.mocked().mock

2 participants