Repository navigation
test: replace proxyquire with sinon in gax, common, error-reporting, translate - #9638
danieljbruce wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Code Review
This pull request removes the dependency on proxyquire across multiple packages, replacing it with standard sinon stubs and manual module caching techniques for mocking, which also allows removing the --proxyquire-shim flag from test scripts. The review feedback suggests two key improvements: first, avoid overriding Module.prototype.require in the Translate tests by directly mutating the cached module exports instead; second, stub the getClient method on the specific auth instance rather than on the GoogleAuth prototype to prevent global prototype pollution.
| const stubs: Record<string, unknown> = { | ||
| '@google-cloud/common': { | ||
| util: fakeUtil, | ||
| Service: FakeService, | ||
| }, | ||
| '@google-cloud/promisify': fakePromisify, | ||
| }).Translate; | ||
| }; | ||
| const mod = Module as unknown as {prototype: {require: NodeRequire}}; | ||
| const origRequire = mod.prototype.require; | ||
| const v2Path = require.resolve('../src/v2'); | ||
| const cached = require.cache[v2Path]; | ||
| delete require.cache[v2Path]; | ||
| mod.prototype.require = Object.assign(function ( | ||
| this: NodeModule, | ||
| id: string, | ||
| ) { | ||
| return id in stubs ? stubs[id] : origRequire.call(this, id); | ||
| }, origRequire); | ||
| try { | ||
| Translate = require('../src/v2').Translate; | ||
| } finally { | ||
| mod.prototype.require = origRequire; | ||
| if (cached) require.cache[v2Path] = cached; | ||
| } |
There was a problem hiding this comment.
Overriding Module.prototype.require is a fragile hack that relies on Node.js internal APIs and can easily break across different Node versions or alternative runtimes (like Bun or Deno). Since @google-cloud/common and @google-cloud/promisify are already loaded and cached in require.cache, you can simply mutate their exported properties on the cached module objects before requiring ../src/v2, and restore them in the finally block. This is much cleaner, safer, and standard.
const common = require('@google-cloud/common');
const origUtil = common.util;
const origService = common.Service;
const origPromisifyAll = pfy.promisifyAll;
common.util = fakeUtil;
common.Service = FakeService;
pfy.promisifyAll = fakePromisify;
const v2Path = require.resolve('../src/v2');
const cached = require.cache[v2Path];
delete require.cache[v2Path];
try {
Translate = require('../src/v2').Translate;
} finally {
common.util = origUtil;
common.Service = origService;
pfy.promisifyAll = origPromisifyAll;
if (cached) require.cache[v2Path] = cached;
}| const getClientStub = sinon | ||
| .stub(auth.GoogleAuth.prototype, 'getClient') | ||
| // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
| .resolves({} as any); |
There was a problem hiding this comment.
Instead of stubbing the prototype of GoogleAuth (which mutates the class prototype globally for all instances), you can stub the getClient method directly on the auth instance. This is safer, avoids prototype pollution, and is more idiomatic.
| const getClientStub = sinon | |
| .stub(auth.GoogleAuth.prototype, 'getClient') | |
| // eslint-disable-next-line @typescript-eslint/no-explicit-any | |
| .resolves({} as any); | |
| const getClientStub = sinon | |
| .stub(auth, 'getClient') | |
| // eslint-disable-next-line @typescript-eslint/no-explicit-any | |
| .resolves({} as any); |
Description
Replaces proxyquire with sinon and direct stubs across four packages.
Impact
Removes --proxyquire-shim from gax, googleapis-common, error-reporting, and translate unit tests.
Changes
core/packages/gax: Replaceproxyquireintest/unit/grpc.tswithsinon.stub(fs, 'existsSync')and remove--proxyquire-shimfrompackage.json.core/packages/nodejs-googleapis-common: Replaceproxyquireintest/test.authplus.tsandtest/test.http2.tswithsinon.stub(auth.GoogleAuth.prototype, 'getClient')andsinon.stub(coreHttp2, 'connect'), and remove--proxyquire-shimfrompackage.json.handwritten/error-reporting: Stubutil.makeAuthenticatedRequestFactoryandRequestHandler.prototype.requestdirectly intest/unit/google-apis/auth-client.tsand remove--proxyquire-shimfrompackage.json.packages/google-cloud-translate: InterceptModule.prototype.requiredirectly intest/index.tsbefore()hook and remove--proxyquire-shimfrompackage.json.Testing
pnpm testunder both Node.js and Bun (JS_RUNTIME=bun) incore/packages/gax,core/packages/nodejs-googleapis-common,handwritten/error-reporting, andpackages/google-cloud-translate.bin/linter.mjs --strict.Alternatives
bin/proxyquire-bun-shim.cjspreload shim.