From 459a6679fe48269c580cb7570ef9111117473390 Mon Sep 17 00:00:00 2001 From: Daniel Bruce Date: Thu, 15 Oct 2026 20:54:38 +0000 Subject: [PATCH] test: replace proxyquire with sinon in gax, common, error-reporting, translate --- core/packages/gax/package.json | 2 +- core/packages/gax/test/unit/grpc.ts | 35 +++++++------- .../nodejs-googleapis-common/package.json | 2 +- .../test/test.authplus.ts | 25 +++++----- .../test/test.http2.ts | 21 ++++---- handwritten/error-reporting/package.json | 2 +- .../test/unit/google-apis/auth-client.ts | 48 +++++++++---------- packages/google-cloud-translate/package.json | 2 +- packages/google-cloud-translate/test/index.ts | 43 ++++++++++++----- 9 files changed, 97 insertions(+), 83 deletions(-) diff --git a/core/packages/gax/package.json b/core/packages/gax/package.json index 7c637b1ba20a..96e47deed478 100644 --- a/core/packages/gax/package.json +++ b/core/packages/gax/package.json @@ -65,7 +65,7 @@ "scripts": { "docs": "jsdoc -c .jsdoc.js", "pretest": "pnpm run compile", - "test": "node ../../../bin/run-test.cjs --proxyquire-shim build/test/unit", + "test": "node ../../../bin/run-test.cjs build/test/unit", "lint": "gts check src samples test", "clean": "gts clean", "compile": "node ./scripts/copy-protos.js && tsc -p . && cp src/*.json build/src && cp -r test/fixtures build/test && cp -r protos build/", diff --git a/core/packages/gax/test/unit/grpc.ts b/core/packages/gax/test/unit/grpc.ts index 76f4207053b9..cf2662eeb2c1 100644 --- a/core/packages/gax/test/unit/grpc.ts +++ b/core/packages/gax/test/unit/grpc.ts @@ -20,9 +20,8 @@ import assert from 'assert'; import * as path from 'path'; -import proxyquire from 'proxyquire'; import * as sinon from 'sinon'; -import {mkdirSync, writeFileSync} from 'fs'; +import fs, {mkdirSync, writeFileSync} from 'fs'; import * as fsp from 'fs/promises'; import {afterEach, describe, it, beforeEach} from 'mocha'; @@ -613,28 +612,28 @@ describe('grpc', () => { const originPath = path.join('test', 'path', 'location'); const includePath = path.join('example', 'import.proto'); + afterEach(() => { + sinon.restore(); + }); + it('should throw an error if a file is not found', () => { - const findIncludePath = proxyquire('../../src/grpc', { - fs: { - existsSync: () => { - return false; - }, - }, - }).GoogleProtoFilesRoot._findIncludePath; - assert.throws(findIncludePath.bind(null, originPath, includePath)); + sinon.stub(fs, 'existsSync').returns(false); + assert.throws( + GoogleProtoFilesRoot._findIncludePath.bind( + null, + originPath, + includePath, + ), + ); }); it('should return the correct resolved import path', () => { const correctPath = path.join('test', 'example', 'import.proto'); - const findIncludePath = proxyquire('../../src/grpc', { - fs: { - existsSync(path: string) { - return path === correctPath; - }, - }, - }).GoogleProtoFilesRoot._findIncludePath; + sinon + .stub(fs, 'existsSync') + .callsFake((p: fs.PathLike) => p === correctPath); assert.strictEqual( - findIncludePath(originPath, includePath), + GoogleProtoFilesRoot._findIncludePath(originPath, includePath), correctPath, ); }); diff --git a/core/packages/nodejs-googleapis-common/package.json b/core/packages/nodejs-googleapis-common/package.json index 5ada806ae27d..a561c40589e5 100644 --- a/core/packages/nodejs-googleapis-common/package.json +++ b/core/packages/nodejs-googleapis-common/package.json @@ -17,7 +17,7 @@ "prebenchmark": "npm run compile", "benchmark": "node build/benchmark/bench.js", "compile": "tsc -p .", - "test": "node ../../../bin/run-test.cjs --proxyquire-shim build/test", + "test": "node ../../../bin/run-test.cjs build/test", "system-test": "node ../../../bin/run-test.cjs build/system-test --timeout 600000", "presystem-test": "npm run compile", "fix": "gts fix", diff --git a/core/packages/nodejs-googleapis-common/test/test.authplus.ts b/core/packages/nodejs-googleapis-common/test/test.authplus.ts index 9a67b52adac6..a2c5b2aae6d5 100644 --- a/core/packages/nodejs-googleapis-common/test/test.authplus.ts +++ b/core/packages/nodejs-googleapis-common/test/test.authplus.ts @@ -13,23 +13,17 @@ // limitations under the License. import * as assert from 'assert'; -import {describe, it} from 'mocha'; -import * as proxyquire from 'proxyquire'; -import * as AuthPlus from '../src/authplus'; +import {afterEach, describe, it} from 'mocha'; +import * as sinon from 'sinon'; +import {AuthPlus} from '../src/authplus'; describe(__filename, () => { - const AuthyPlus: typeof AuthPlus = proxyquire('../src/authplus', { - 'google-auth-library': { - GoogleAuth: class { - async getClient() { - return {}; - } - }, - }, + afterEach(() => { + sinon.restore(); }); it('should expose auth classes', () => { - const auth = new AuthyPlus.AuthPlus(); + const auth = new AuthPlus(); assert.ok(auth.JWT); assert.ok(auth.Compute); assert.ok(auth.OAuth2); @@ -40,8 +34,13 @@ describe(__filename, () => { }); it('should get a new client', async () => { - const auth = new AuthyPlus.AuthPlus(); + const auth = new AuthPlus(); + const getClientStub = sinon + .stub(auth.GoogleAuth.prototype, 'getClient') + // eslint-disable-next-line @typescript-eslint/no-explicit-any + .resolves({} as any); const client = await auth.getClient(); assert.deepStrictEqual(client, {}); + assert.strictEqual(getClientStub.calledOnce, true); }); }); diff --git a/core/packages/nodejs-googleapis-common/test/test.http2.ts b/core/packages/nodejs-googleapis-common/test/test.http2.ts index 1da040be4074..291deae4b60b 100644 --- a/core/packages/nodejs-googleapis-common/test/test.http2.ts +++ b/core/packages/nodejs-googleapis-common/test/test.http2.ts @@ -14,14 +14,13 @@ import * as assert from 'assert'; import * as coreHttp2 from 'http2'; -import {describe, it, before, beforeEach} from 'mocha'; +import {describe, it, before, beforeEach, after} from 'mocha'; import {gzipSync} from 'zlib'; -import * as proxyquire from 'proxyquire'; import * as sinon from 'sinon'; import {Duplex, Readable} from 'stream'; import {EventEmitter} from 'events'; import {GaxiosResponse} from 'gaxios'; -import * as http2Types from '../src/http2'; +import * as http2 from '../src/http2'; import {GoogleAuth} from '../src'; @@ -59,13 +58,15 @@ describe('http2', () => { return (connectStub || (() => {}))(host); } let connectStub: Function; - let http2: typeof http2Types; + let connectSinonStub: sinon.SinonStub; before(() => { - http2 = proxyquire('../src/http2', { - http2: { - connect: fakeConnect, - }, - }); + connectSinonStub = sinon + .stub(coreHttp2, 'connect') + // eslint-disable-next-line @typescript-eslint/no-explicit-any + .callsFake(fakeConnect as any); + }); + after(() => { + connectSinonStub.restore(); }); let requestStream: Duplex; @@ -153,7 +154,7 @@ describe('http2', () => { requestStream.push(Buffer.from('{}')); requestStream.push(null); await resPromise; - await new Promise(r => setTimeout(r, 500)); + await new Promise(resolve => setTimeout(resolve, 500)); assert.strictEqual(Object.keys(http2.sessions).length, 0); }); diff --git a/handwritten/error-reporting/package.json b/handwritten/error-reporting/package.json index 99be138c9e81..145b0be715b3 100644 --- a/handwritten/error-reporting/package.json +++ b/handwritten/error-reporting/package.json @@ -23,7 +23,7 @@ "lint": "gts check", "presystem-test": "pnpm run compile", "system-test": "MOCHA_THROW_DEPRECATION=false node ../../bin/run-test.cjs build/system-test", - "test": "node ../../bin/run-test.cjs --proxyquire-shim build/test/unit", + "test": "node ../../bin/run-test.cjs build/test/unit", "clean": "gts clean", "compile": "tsc -p .", "fix": "gts fix", diff --git a/handwritten/error-reporting/test/unit/google-apis/auth-client.ts b/handwritten/error-reporting/test/unit/google-apis/auth-client.ts index 712dc4fb95af..205e352301ba 100644 --- a/handwritten/error-reporting/test/unit/google-apis/auth-client.ts +++ b/handwritten/error-reporting/test/unit/google-apis/auth-client.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import * as proxyquire from 'proxyquire'; +import {util} from '@google-cloud/common'; import {describe, beforeEach, afterEach, it} from 'mocha'; import { @@ -20,6 +20,7 @@ import { ConfigurationOptions, Logger, } from '../../../src/configuration'; +import {RequestHandler} from '../../../src/google-apis/auth-client'; import {deepStrictEqual} from '../../util'; function verifyReportedMessage( @@ -28,28 +29,6 @@ function verifyReportedMessage( expectedLogs: {error?: string; info?: string; warn?: string}, done: () => void, ) { - class ServiceStub { - authClient: {}; - request: {}; - constructor() { - this.authClient = { - async getAccessToken() { - if (errToReturn) { - throw errToReturn; - } - return 'some-token'; - }, - }; - this.request = () => {}; - } - } - - const RequestHandler = proxyquire('../../../src/google-apis/auth-client', { - '@google-cloud/common': { - Service: ServiceStub, - }, - }).RequestHandler; - const logs: {error?: string; info?: string; warn?: string} = {}; const logger = { error(text: string) { @@ -72,8 +51,27 @@ function verifyReportedMessage( }, } as {} as Logger; const config2 = new Configuration(config1, logger); - // tslint:disable-next-line:no-unused-expression - new RequestHandler(config2, logger); + const origMakeAuthFactory = util.makeAuthenticatedRequestFactory; + const origRequest = RequestHandler.prototype.request; + util.makeAuthenticatedRequestFactory = (() => ({ + authClient: { + async getAccessToken() { + if (errToReturn) { + throw errToReturn; + } + return 'some-token'; + }, + }, + getCredentials: {}, + })) as unknown as typeof util.makeAuthenticatedRequestFactory; + RequestHandler.prototype.request = (() => {}) as typeof origRequest; + try { + // tslint:disable-next-line:no-unused-expression + new RequestHandler(config2, logger); + } finally { + util.makeAuthenticatedRequestFactory = origMakeAuthFactory; + RequestHandler.prototype.request = origRequest; + } setImmediate(() => { deepStrictEqual(logs, expectedLogs); done(); diff --git a/packages/google-cloud-translate/package.json b/packages/google-cloud-translate/package.json index 328f2a0179e5..b7edd2c81e2d 100644 --- a/packages/google-cloud-translate/package.json +++ b/packages/google-cloud-translate/package.json @@ -44,7 +44,7 @@ "postpack": "minifyProtoJson", "samples-test": "cd samples/ && npm link ../ && npm i && npm test", "system-test": "node ../../bin/run-test.cjs --config ../../.mocharc.cjs --no-parallel build/system-test", - "test": "node ../../bin/run-test.cjs --proxyquire-shim --config ../../.mocharc.cjs build/test" + "test": "node ../../bin/run-test.cjs --config ../../.mocharc.cjs build/test" }, "dependencies": { "@google-cloud/common": "^8.0.1", diff --git a/packages/google-cloud-translate/test/index.ts b/packages/google-cloud-translate/test/index.ts index 8e6d714e057a..3e03bbd748cf 100644 --- a/packages/google-cloud-translate/test/index.ts +++ b/packages/google-cloud-translate/test/index.ts @@ -21,7 +21,7 @@ import * as pfy from '@google-cloud/promisify'; import * as assert from 'assert'; import {after, afterEach, before, beforeEach, describe, it} from 'mocha'; import * as extend from 'extend'; -import * as proxyquire from 'proxyquire'; +import * as Module from 'module'; import * as r from 'request'; import * as orig from '../src'; @@ -44,7 +44,7 @@ const fakeUtil = extend({}, util, { makeRequest( opts: DecorateRequestOptions, cfg: MakeRequestConfig, - cb: BodyResponseCallback + cb: BodyResponseCallback, ) { if (makeRequestOverride) { return makeRequestOverride(opts, cfg, cb); @@ -74,13 +74,30 @@ describe('Translate v2', () => { let translate: any; before(() => { - Translate = proxyquire('../src/v2', { + const stubs: Record = { '@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; + } }); beforeEach(() => { @@ -266,7 +283,7 @@ describe('Translate v2', () => { assert.strictEqual(apiResponse_, apiResponse); assert.deepStrictEqual(apiResponse_, originalApiResponse); done(); - } + }, ); }); }); @@ -314,7 +331,7 @@ describe('Translate v2', () => { assert.strictEqual(languages, null); assert.strictEqual(apiResponse_, apiResponse); done(); - } + }, ); }); }); @@ -359,7 +376,7 @@ describe('Translate v2', () => { assert.deepStrictEqual(languages, expectedResults); assert.strictEqual(apiResponse_, apiResponse); done(); - } + }, ); }); }); @@ -407,7 +424,7 @@ describe('Translate v2', () => { from: SOURCE_LANG_CODE, to: TARGET_LANG_CODE, }, - assert.ifError + assert.ifError, ); }); }); @@ -496,7 +513,7 @@ describe('Translate v2', () => { assert.strictEqual(translations, null); assert.strictEqual(resp, apiResponse); done(); - } + }, ); }); }); @@ -531,7 +548,7 @@ describe('Translate v2', () => { assert.deepStrictEqual(translations, expectedResults); assert.strictEqual(resp, apiResponse); done(); - } + }, ); }); @@ -552,7 +569,7 @@ describe('Translate v2', () => { assert.ifError(err); assert.deepStrictEqual(translations, [expectedResults]); done(); - } + }, ); }); }); @@ -584,7 +601,7 @@ describe('Translate v2', () => { FakeService.prototype.request = ( reqOpts: r.Options, - callback: Function + callback: Function, ) => { assert.strictEqual(reqOpts, fakeOptions); callback(); @@ -640,7 +657,7 @@ describe('Translate v2', () => { makeRequestOverride = ( reqOpts: r.Options, options: {}, - callback: Function + callback: Function, ) => { assert.deepStrictEqual(reqOpts, expectedReqOpts); assert.strictEqual(options, translate.options);