Issue
I've written some unit tests using jest for a Github action which I am writing in Typescript. The code is all sound and the tests passing, but the linter is not happy.
The actual method under test is:
const JWKS = jose.createRemoteJWKSet<jose.KeyLike>(new URL(`${idp_url}/${jwks_endpoint}`))
I've created a small method that completes the implementation of the mock, but the linter is not happy about the use of any
and I'm not sure how to narrow it:
export const buildCreateRemoteJWKSetMock = (
createRemoteJWKSetMock: jest.SpyInstance<any, any, any>
): void => {
createRemoteJWKSetMock.mockImplementation(
(
url: URL
): ((
protectedHeader?: jose.JWSHeaderParameters | undefined,
token?: jose.FlattenedJWSInput | undefined
) => Promise<jose.KeyLike>) =>
(protectedHeader, token) =>
Promise.resolve(testConstants.empty as unknown as jose.KeyLike)
)
}
Is there an elegant way around this? I have quite a few of these in my code.
Solution
Don't make a function to install the mock for you. Instead just make a function that is the mock and install where you need it. Then you don't have to pass strongly typed spies around at all.
So first make the mock itself a function:
const createRemoteJWKSetMock = (
url: URL
): ((
protectedHeader?: jose.JWSHeaderParameters | undefined,
token?: jose.FlattenedJWSInput | undefined
) => Promise<jose.KeyLike>) =>
(protectedHeader, token) =>
Promise.resolve(testConstants.empty as unknown as jose.KeyLike)
Then pass that to mySpy.mockImplementation
in your test file:
jest
.spyOn(jose, 'createRemoteJWKSet')
.mockImplementation(createRemoteJWKSetMock)
At each call site where you use that, that's really not very different than this:
buildCreateRemoteJWKSetMock(
jest.spyOn(jose, 'createRemoteJWKSet')
)
And I would argue that the former is easier to read and maintain.
Answered By - Alex Wayne
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.