I am using the @okta/jwt-verifier library to verify JWT's and I am trying to test this functionality by mocking the various responses from the library.
I can mock the verifyAccessToken
method once for all tests however I am unsure exactly how to modify this mocked implementation to different tests i.e. the default will be a successful response returning a token however for some tests I need to mock the responses for a failed token verification i.e. an expired token.
This is what I have so far:
Implementation
const oktaJwtVerifier = new OktaJwtVerifier({
issuer: "issuer domain",
});
export const verifyAccessToken = async (token: string) =>
oktaJwtVerifier.verifyAccessToken(token, "audience");
Mock in tests
jest.mock("@okta/jwt-verifier", () => {
return jest.fn().mockImplementation(() => ({
verifyAccessToken: () => ({
foo: "bar",
}),
}));
});
This mock works as expected and when the code tested call the verifyAccessToken
method the mocked implementation is returned.
However I would I return a different response for different tests in the same test suite?
Don't pass the factory
argument to jest.mock()
, jest.mock()
will mock
a module with an auto-mocked version. You can call .mockResolvedValueOnce()
in each test case to provide different mock values later.
You can get the instance of the mocked OktaJwtVerifier
class via mockFn.mock.instance
An array that contains all the object instances that have been instantiated from this mock function using
new
.
Handle the TS type for mocks using the mocked
helper function of the ts-jest
module. If you are using the latest Jest, use jest.mocked(source, options?)
instead.
Note: I created a simple string as the resolved value for verifyAccessToken()
method, did not match the real TS return type.
E.g.
main.ts
:
import OktaJwtVerifier from '@okta/jwt-verifier';
const oktaJwtVerifier = new OktaJwtVerifier({
issuer: "issuer domain",
});
export const verifyAccessToken = async (token: string) =>
oktaJwtVerifier.verifyAccessToken(token, "audience");
main.test.ts
:
import OktaJwtVerifier from '@okta/jwt-verifier';
import { verifyAccessToken } from './main';
import { mocked } from 'ts-jest';
jest.mock("@okta/jwt-verifier");
const OktaJwtVerifierMock = mocked(OktaJwtVerifier)
const oktaJwtVerifierInstance = mocked(OktaJwtVerifierMock.mock.instances[0]);
describe('76422353', () => {
test('should pass 1', async () => {
oktaJwtVerifierInstance.verifyAccessToken.mockResolvedValueOnce('a' as any);
const actual = await verifyAccessToken('1');
expect(actual).toBe('a');
});
test('should pass 2', async () => {
oktaJwtVerifierInstance.verifyAccessToken.mockResolvedValueOnce('b' as any);
const actual = await verifyAccessToken('2');
expect(actual).toBe('b');
});
});
Test result:
PASS stackoverflow/76422353/main.test.ts (15.361 s)
76422353
✓ should pass 1 (2 ms)
✓ should pass 2
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 18.347 s
package versions:
"@okta/jwt-verifier": "^3.0.1",
"jest": "^26.6.3",
"ts-jest": "^26.4.4",