nahum
nahum

Reputation: 21

Mock jose.jwtVerify with jest

I try to mock jose.jwtVerify and get different errors on different solutions I saw.

The errors I got:

  1. jest error: property is not declared configurable
  2. Cannot assign to 'type' because it is a read-only property

I can't find a working solution to mock exported read only functions.

I'm using the following configurations:

tsconfig:

{
    "extends": "@tsconfig/node20/tsconfig.json",
    "compilerOptions": {
        "declaration": true,
        "outDir": "./dist/",
        "noUnusedParameters": false,
        "noPropertyAccessFromIndexSignature": false,
        "resolveJsonModule": true
    },
}

jest config:

module.exports = {
    preset: 'ts-jest',
    testEnvironment: 'node',
    testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.(ts?)$',
    moduleNameMapper: {
        '^(\\.{1,2}/.*)\\.js$': '$1',
    },
    extensionsToTreatAsEsm: ['.ts'],
    transform: {
        '^.+\\.tsx?$': [
            'ts-jest',
            {
                useESM: true,
            },
        ],
    },

};

package.json:

{
  "name": "test",
  "version": "0.0.1",
  "description": "test",
  "main": "index.js",
  "type": "module",
  "scripts": {
    "build": "npm run clean && npm run copy-files && npm run tsc",
    "copy-files": "copyfiles -e \"!{*.md,package?(-lock).json}\" \"**/*.*\" dist",
    "clean": "rimraf ./dist",
    "tsc": "tsc -p tsconfig.build.json",
    "deploy": "cdktf deploy",
    "lint": "npx eslint . --ext .ts,.tsx",
    "test": "node --experimental-vm-modules ./node_modules/.bin/jest --maxWorkers=2 -c jest.config.cjs",
    "coverage": "jest -c jest-cov.config.cjs"
  },
  "author": "test",
  "license": "test",
  "devDependencies": {
    "@cdktf/provider-aws": "18.0.6",
    "@jest/globals": "29.7.0",
    "@tsconfig/node20": "20.1.2",
    "@types/aws-lambda": "8.10.130",
    "@types/jest": "29.5.11",
    "@types/lodash": "^4.14.188",
    "@types/node": "20.10.5",
    "@typescript-eslint/eslint-plugin": "6.16.0",
    "@typescript-eslint/parser": "6.16.0",
    "cdktf": "0.19.1",
    "constructs": "10.3.0",
    "copyfiles": "2.4.1",
    "eslint": "8.38.0",
    "eslint-config-airbnb-base": "15.0.0",
    "eslint-config-airbnb-typescript": "17.1.0",
    "eslint-plugin-import": "2.28.0",
    "eslint-plugin-jest": "27.2.3",
    "jest": "29.7.0",
    "jest-junit": "16.0.0",
    "lodash": "^4.17.21",
    "rimraf": "5.0.5",
    "ts-jest": "29.1.1",
    "ts-node": "10.9.2",
    "ts-sinon": "^2.0.2",
    "typescript": "5.3.3"
  },
  "dependencies": {
    "@aws-sdk/client-dynamodb": "3.468.0",
    "@types/rewire": "^2.5.30",
    "aws-jwt-verify": "4.0.0",
    "aws-sdk": "2.1422.0",
    "axios": "1.6.2",
    "dotenv": "16.3.1",
    "jose": "5.2.0",
    "nanoid": "3.3.6",
    "rewire": "^7.0.0",
    "sinon": "^17.0.1"
  }
}

These are the things I have already tried:

1. jest.spyOn(jose, 'jwtVerify', 'get').mockReturnValue('ok')
2. Object.defineProperty(jose, 'jwtVerify', {
            get: jest.fn(() => 'bar'),
        });
3. jest.replaceProperty(jose, 'jwtVerify', 'ok');
4. jest.mock('jose', () => {
    return {
        jwtVerify: () => 'ok',
    };
});

Upvotes: 0

Views: 626

Answers (2)

Igor Maia
Igor Maia

Reputation: 1

I was struggling with the same problem as you with Jest and Jose library. I tested a few options and none of them worked. Thanks @thuynging for the response.

Translating it to Jest would be

import * as jose from 'jose';

describe('Testing feature', () => {

function createVerifyPayload(): Promise<jose.JWTPayload> {
    return Promise.resolve({
        scope: 'custom:scope'
    });
};

test('Test case', async () => {
    jest.spyOn(jose, 'jwtVerify').mockReturnValue(
        Promise.resolve<jose.JWTVerifyResult & jose.ResolvedKey<jose.KeyLike>>({
            payload: await createVerifyPayload(),
            protectedHeader: {"alg": "test"},
            "key": {"type": "test"}
        }));
});

Upvotes: 0

thuynging
thuynging

Reputation: 1

I use vitest but I think it would be similar to jest.

import * as jose from "jose";
import {describe, it, vi} from "vitest";


function createVerifyPayload(): Promise<JWTPayload> {
    return Promise.resolve({
        sub: "1",
        role: "1",
        iat: 1,
        exp: 1,
    });
}


describe("test", () => {
  it("test", async () => {
    vi.spyOn(jose, "jwtVerify").mockReturnValue(
      Promise.resolve<JWTVerifyResult<unknown> & ResolvedKey<KeyLike>>({
                  payload: await createVerifyPayload(),
                  protectedHeader: {"alg": "test"},
                  "key": {"type": "test"}
     }));

  });
};

I hope this helps!

Upvotes: 0

Related Questions