1

I'm wanting to mock a method of a class returned from a module's exports, and I'm having a hard time setting up a Jest test to do so.

Here's what I have:

// src/jwks.js

const jwksClient = require('jwks-rsa')
const client = jwksClient({...})
module.exports = client
// src/auth.js

const jwksClient = require('./jwks')

function getKey (header, callback) {
  jwksClient.getSigningKey(header.kid, function (err, key) {
    console.log("inside getSigningKey")
    var signingKey = key.publicKey || key.rsaPublicKey
    callback(err, signingKey)
  })
}

exports.getKey = getKey
// src/auth.test.js

const jwksClient = require('./jwks')
const { getKey } = require('./auth')

const mockGetSigningKey = jest.fn(() => {
    console.log("mockGetSigningKey called")
    return {
        publickey: "the-key"
    }
})

jest.mock('./jwks', () => {
  return jest.fn().mockImplementation(() => {
    return {
        getSigningKey: mockGetSigningKey
    }
  })
})

test('test mocked behavior', () => {
    getKey("somekey", (err, key) => {
        console.log("received key: " + key)
    })
}

I get the following error: TypeError: jwksClient.getSigningKey is not a function

  2 | 
  3 | function getKey (header, callback) {
> 4 |   jwksClient.getSigningKey(header.kid, function (err, key) {
    |              ^
  5 |     console.log("inside getSigningKey")
  6 |     var signingKey = key.publicKey || key.rsaPublicKey
  7 |     callback(err, signingKey)

How do I go about doing this properly? I've tried a lot of different variations and none of them are working for me.

1 Answer 1

1

You didn't mock ./jwks module correctly. Here is the solution:

auth.js:

const jwksClient = require('./jwks');

function getKey(header, callback) {
  jwksClient.getSigningKey(header.kid, function (err, key) {
    console.log('inside getSigningKey');
    var signingKey = key.publicKey || key.rsaPublicKey;
    callback(err, signingKey);
  });
}

exports.getKey = getKey;

jwks.js:

// whatever

auth.test.js:

const { getKey } = require('./auth');
const jwksClient = require('./jwks');

jest.mock('./jwks', () => {
  return { getSigningKey: jest.fn() };
});

describe('62544352', () => {
  it('should pass', () => {
    jwksClient.getSigningKey.mockImplementationOnce((key, callback) => {
      const key = { publicKey: 'publicKey' };
      callback(null, key);
    });
    const mCallback = jest.fn();
    getKey({ kid: 'someKey' }, mCallback);
    expect(jwksClient.getSigningKey).toBeCalledWith('someKey', expect.any(Function));
    expect(mCallback).toBeCalledWith(null, 'publicKey');
  });
});

unit test result with coverage report:

 PASS  stackoverflow/62544352/auth.test.js (10.232s)
  62544352
    ✓ should pass (28ms)

  console.log
    inside getSigningKey

      at stackoverflow/62544352/auth.js:5:13

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |     100 |       50 |     100 |     100 |                   
 auth.js  |     100 |       50 |     100 |     100 | 6                 
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        11.65s
Sign up to request clarification or add additional context in comments.

1 Comment

Ah, good catch! Worked like a charm. Thank you very much.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.