TypeError: Cannot read property 'sign' of undefined [JWT / Nestjs / e2e tests]

4.2k views Asked by At

I need to generate a Jwt Bearer Token for my e2e tests. As the process it a bit tedious, and because that's not what I am trying to test, I'd like to bypass it by directly getting instead of going through the 2FA real process.

Unfortunately I keep getting the following error:

 TypeError: Cannot read property 'sign' of undefined

      150 |
      151 |     function getBearerToken(candidateId: number) {
    > 152 |       return jwtService.sign({ sub: candidateId.toString() })
          |                         ^
      153 |     }
      154 |   })
      155 | })

      at getBearerToken (app.e2e-spec.ts:152:25)
      at Object.<anonymous> (app.e2e-spec.ts:127:21)
describe('Bookmarks Module', () => {
    let bearerToken: string
    let jwtService: JwtService

    beforeEach(() => {
      bearerToken = getBearerToken(1)
      jwtService = new JwtService({
        secret: process.env.JWT_SECRET,
        signOptions: { expiresIn: '1h' },
      })
    })

    test('/v1/bookmarks/ (GET) [auth]', () => {
      return expectCorrectAuthenticatedGetResponse(
        `${V1_PREFIX}/bookmarks/`,
        bearerToken
      )
    })

    test('/v1/bookmarks/{id} (POST) [auth]', () => {
      const DATA = { offerId: 19 }
      return expectCorrectAuthenticatedPostResponse(
        `${V1_PREFIX}/bookmarks/${DATA.offerId}`,
        DATA,
        bearerToken
      )
    })

    function getBearerToken(candidateId: number) {
      return jwtService.sign({ sub: candidateId.toString() })
    }
  })
3

There are 3 answers

0
Stéphane Veyret On BEST ANSWER

You call jwtService.sign() in getBearerToken() which is itself called in beforeEach(), just before jwtService is initialized. So jwtService is still undefined when you try to use it. You should invert the lines in beforeEach():

    beforeEach(() => {
      jwtService = new JwtService({
        secret: process.env.JWT_SECRET,
        signOptions: { expiresIn: '1h' },
      })
      bearerToken = getBearerToken(1)
    })
0
Andy On

For me was a different issue. [node v18]

changed this:
import jwt from 'jsonwebtoken'
to this:
import * as jwt from 'jsonwebtoken'
or each individual property:
import {sign, verify, JwtPayload} from "jsonwebtoken";

and back in business.

2
Isaacs Katongole On

I have faced the same issue when I import jwt like:

import { jwt } from "jsonwebtoken";

So I changed it to:

var jwt = require('jsonwebtoken');

or

import jwt from "jsonwebtoken";

and it worked it

I don't know why it worked.