-
Notifications
You must be signed in to change notification settings - Fork 29.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
breaking change in 21.7.0 when mocking fetch #52015
Comments
This is another simplified test case: import { mock } from "node:test";
mock.method(globalThis, "fetch", async () => ({
text: async () => "foo",
}));
const response = await fetch("https://bar.baz/");
const text = await response.text();
console.log(text);
mock.restoreAll(); |
@nodejs/test_runner @joyeecheung |
It appears that this issue can be resolved by reintroducing the following code within the
As a newcomer, I'm eager to contribute and learn. If there are any errors in my understanding, I would appreciate your guidance. Thank you for your assistance! |
It seems to me that it’s t.mock that should be fixed, other wise it would not work with user land objects that has a similar descriptor. |
I think the bug comes from the The descriptor of property console.log(Object.getOwnPropertyDescriptor(globalThis, "fetch"));
fetch;
console.log(Object.getOwnPropertyDescriptor(globalThis, "fetch"));
|
1 similar comment
You could directly define the ObjectDefineProperty(globalThis, 'fetch', {
__proto__: null,
writable: true,
value: function fetch(input, init = undefined) {
// Loading undici alone lead to promises which breaks lots of tests so we
// have to load it really lazily for now.
const { fetch: impl } = require('internal/deps/undici/undici');
return impl(input, init);
},
}); |
At end of the day, it seems to be a design issue with the mocking libraries, as their API forces users to know and differentiate between getters and values even though users may only care about hijacking or recording the access, but don’t care about whether the access is done via a getter or not. For example with Sinon I think you would then need to use a spy with .get(), and this applies to user objects too sinonjs/sinon#1545 That said for properties that are themselves methods, like in the case of fetch, doing the lazy loading inside the value method seems to be a good compromise if it helps users work around this issue with the mocking libraries. I am not sure about FormData and friends because as constructors wrapping them complicates instanceof, but they may be less necessary to mock anyway. |
In any case, isn't it still considered a breaking change and should be in a major node version change? |
Object.defineProperty is updated to lazily load the undici dependency for the fetch method. This change allows for simpler and more reliable mocking of the fetch method for testing purposes, resolving issues encountered with premature method invocation during testing. Fixes: nodejs#52015
There's the same problem with Node v20.12.0:
|
Same problem reproduced with Node v20.12.1 |
Object.defineProperty is updated to lazily load the undici dependency for the fetch method. This change allows for simpler and more reliable mocking of the fetch method for testing purposes, resolving issues encountered with premature method invocation during testing. Fixes: nodejs#52015
The bug is also in v22.0.0: ce56887 |
Is there a reason why this issue is marked as closed? The issue still persists into v22.0.0 and wasn't fixed by #52275 . Has the discussion moved somewhere else? |
#52275 is not yet in v22. It should be part of the next release. |
Object.defineProperty is updated to lazily load the undici dependency for the fetch method. This change allows for simpler and more reliable mocking of the fetch method for testing purposes, resolving issues encountered with premature method invocation during testing. Fixes: #52015 PR-URL: #52275 Reviewed-By: Moshe Atlow <moshe@atlow.co.il> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Chemi Atlow <chemi@atlow.co.il> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Object.defineProperty is updated to lazily load the undici dependency for the fetch method. This change allows for simpler and more reliable mocking of the fetch method for testing purposes, resolving issues encountered with premature method invocation during testing. Fixes: #52015 PR-URL: #52275 Reviewed-By: Moshe Atlow <moshe@atlow.co.il> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Chemi Atlow <chemi@atlow.co.il> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Object.defineProperty is updated to lazily load the undici dependency for the fetch method. This change allows for simpler and more reliable mocking of the fetch method for testing purposes, resolving issues encountered with premature method invocation during testing. Fixes: #52015 PR-URL: #52275 Reviewed-By: Moshe Atlow <moshe@atlow.co.il> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Chemi Atlow <chemi@atlow.co.il> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Version
21.7.0
Platform
Darwin Stevens-MacBook-Pro.local 23.2.0 Darwin Kernel Version 23.2.0: Wed Nov 15 21:54:55 PST 2023; root:xnu-10002.61.3~2/RELEASE_ARM64_T8122 arm64
Subsystem
No response
What steps will reproduce the bug?
which produces:
to fix the break, i have to reference
global.fetch
before mocking it...ie:How often does it reproduce? Is there a required condition?
Consistently
What is the expected behavior? Why is that the expected behavior?
Should not break existing code on a minor or patch semver change of node.
What do you see instead?
It breaks
Additional information
This is the PR which introduced the break: #51598 (comment)
The text was updated successfully, but these errors were encountered: