Search code examples
javascriptnode.jssinon

stubbing a method for all instances of a class


Trying to stub a method getSigningKey of jwksClient. However, it actually executes the non stub version of the function and returns an error instead of the mockResponse. How to stub it such that it will return the mockResponse instead?

const jwksClient = require('jwks-rsa');
sinon.stub(jwksClient(sinon.match.any), 'getSigningKey').callsArgWith(1, null, mockResponse)
const client = auth0authorizer.jwksClient({
     cache: true,
     cacheMaxEntries: 5, // Default value
     cacheMaxAge: ms('10h'), // Default value
     jwksUri: jwksUri
});
client.getSigningKey('abc',(err,key) => {
  // doesn't stub returns error
})

Solution

  • This code looks more complex than necessary, especially the Sinon part. I am assuming auth0authorizer.jwksClient is a typo in your example code, and that you really meant just jwksClient.

    If you mean to stub the instance, you need to stub the generated instance, not a non-existing method on the factory method (which is what you are doing!).

    That would simply mean

    const client = jwksClient({
         cache: true,
         jwksUri: jwksUri
    });
    sinon.stub(client, 'getSigningKey').callsArgWith(1, null, mockResponse)
    

    But if the problem is that you have no access to the generated client object for some reason, such as it being generated outside of your control, you will have to stub the prototype of the jwksClient. It looks like you are not able to import the JwksClient class directly, as the lib is transpiled by Babel, and does not export the class. In that case, you can make use of Object.getPrototypeOf().

    Just invoke the jwksClient function first, and get hold of the dummy object returned. We will only use this to modify the prototype:

     const proto = Object.getPrototypeOf( jwksClient(options) );
     // create stub on the class method
     const stub = sinon.stub(proto, 'getSigningKey').callsArgWith(1, null, mockResponse);
     // proceed with test as normal
    

    Just remember to restore the stub afterwards, as you might have weird errors in later tests otherwise :-)

    Discloser: I am on the Sinon team.