TL;DR: Wrap the dependency and stub your wrapper; don't try to stub the dependency.
The solution I found was to:
// My wrapper module, PubSub.ts
const pubSub = new PubSub()
export async function publishBytes(topicName: string, bytes: Uint8Array): Promise<void> {
const topic = pubSub.topic(topicName)
const data = Buffer.from(bytes)
await topic.publishMessage({ data })
}
// My test code
import * as PubSub from "./PubSub"
sinon.spy(PubSub, "publishBytes")...