typescriptgoogle-cloud-functionssinonproxyquire

How can I stub a function that belongs to a class in an external dependency?


I want to test a Google Cloud Function written in Typescript, and the function calls publishMessage, a member function of the Topic class. How can I make a unit test capture the argument that got passed to publishMessage so that I can validate it?

I've tried to understand how to do it using sinon or proxyquire, but all the examples are using javascript's require() and/or are stubbing module-level static functions. I don't understand how that maps to using Typescript's import and to stubbing a method that's inside of a class.

The code I want to test looks something like this:

import {PubSub} from "@google-cloud/pubsub"

class Foo {
    private pubSub = new PubSub()
    private topic = this.pubSub.topic("foo-topic")

    public publishMessage() {
        const data = Buffer.from("content")
        return this.topic.publishMessage({data})
    }
}

const foo = new Foo()

// This function is what the test will have access to and operate on.
export const fooPublishMessage = foo.publishMessage

In case it matters, I'm using mocha and chai for testing, but I'm not married to them.


Solution

  • 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")...