Search code examples
typescriptjestjsbackend

Type error: mockReturnValueOnce from jest.spyOn() inferring argument type as void


I'm trying to mock the return value from bcrypt's compare method. The return type of compare method is a Promise<boolean>. When I write this line "jest.spyOn(bcrypt, 'compare').mockReturnValueOnce()", the argument type inferred to mockReturnValueOnce is being void and not Promise<boolean>. So, I can't mock the return value with this "new Promise(resolve => resolve(false))" because I got a TypeScript error: "TS2345: Argument of type 'Promise<unknown>' is not assignable to parameter of type 'void'".

Thank you.

import bcrypt from 'bcrypt'
import { BcryptAdapter } from './bcrypt-adapter'

jest.mock('bcrypt', () => ({
  async hash (): Promise<string> {
    return await new Promise(resolve => resolve('hash'))
  },

  async compare (): Promise<boolean> {
    return await new Promise(resolve => resolve(true))
  }
}))

const salt = 12
const makeSut = (): BcryptAdapter => {
  return new BcryptAdapter(salt)
}

describe('Bcrypt Adapter', () => {
  test('Should return false when compare fails', async () => {
    const sut = makeSut()
    jest.spyOn(bcrypt, 'compare').mockReturnValueOnce(new Promise(resolve => resolve(false)))
    const isValid = await sut.compare('any_value', 'any_hash')
    expect(isValid).toBe(false)
  })
})

Dependencies:

"devDependencies": {
    "@shelf/jest-mongodb": "^2.0.1",
    "@types/bcrypt": "^5.0.0",
    "@types/express": "^4.17.13",
    "@types/jest": "^26.0.24",
    "@types/mongodb": "^3.6.20",
    "@types/node": "^15.14.0",
    "@types/supertest": "^2.0.11",
    "@types/validator": "^13.6.3",
    "@typescript-eslint/eslint-plugin": "^4.28.4",
    "eslint": "^7.31.0",
    "eslint-config-standard-with-typescript": "^20.0.0",
    "eslint-plugin-import": "^2.23.4",
    "eslint-plugin-node": "^11.1.0",
    "eslint-plugin-promise": "^4.3.1",
    "git-commit-msg-linter": "^3.2.6",
    "husky": "^7.0.1",
    "jest": "^27.0.6",
    "lint-staged": "^11.1.0",
    "sucrase": "^3.20.0",
    "supertest": "^6.1.4",
    "ts-jest": "^27.0.4",
    "typescript": "^4.3.5"
  },
  "dependencies": {
    "bcrypt": "^5.0.1",
    "express": "^4.17.1",
    "fast-glob": "^3.2.7",
    "mongodb": "^3.6.10",
    "validator": "^13.6.0"
  }

Solution

  • Dude try this:

    jest.spyOn(bcrypt, 'compare').mockImplementation(() => Promise.resolve(false))
    

    It worked for me.