I am trying to learn vitest, in my createUser
controller I generate a hashed password using genSalt
and hash
from bcryptjs
in my test file I mocked the two functions using this way
vi.mock("bcryptjs", () => ({
genSalt: vi.fn(),
hash: vi.fn(),
}));
it works but i wanted to write a test that makes sure that the password in the user object is a hashed password, so I wanted to restore the original implementation of genSalt
and hash
, I found a tutorial online that says I should import the acutal module using vi.importActual
and mock the two functions implementation with the original imports.
it("User is created with a hashed password", async () => {
req.body = { name: "foo", email: "[email protected]", password: "1234" };
const genSaltOriginal = (await vi.importActual<any>("bcryptjs")).genSalt;
const hashOriginal = (await vi.importActual<any>("bcryptjs")).hash;
(genSalt as Mock).mockImplementationOnce(genSaltOriginal);
(hash as Mock).mockImplementationOnce(hashOriginal);
await createUser(req as Request, res as Response, fakeNext as NextFunction);
This does not work, when I log the salt and hashed password values they return undefined, and for some reason when I comment out (hash as Mock).mockImplementationOnce(hashOriginal)
the genSalt
works and returns an actual salt when I log it to the console, but enabling this line breaks it, also here is the code for hash generation:
let salt;
let hashedPassword;
try {
salt = await genSalt(10);
hashedPassword = await hash(password, salt);
} catch (err) {
next(new CustomError(undefined, 500, `Password hashing failed\n${err}`));
return;
}
I am trying to learn vitest, in my createUser
controller I generate a hashed password using genSalt
and hash
from bcryptjs
in my test file I mocked the two functions using this way
vi.mock("bcryptjs", () => ({
genSalt: vi.fn(),
hash: vi.fn(),
}));
it works but i wanted to write a test that makes sure that the password in the user object is a hashed password, so I wanted to restore the original implementation of genSalt
and hash
, I found a tutorial online that says I should import the acutal module using vi.importActual
and mock the two functions implementation with the original imports.
it("User is created with a hashed password", async () => {
req.body = { name: "foo", email: "[email protected]", password: "1234" };
const genSaltOriginal = (await vi.importActual<any>("bcryptjs")).genSalt;
const hashOriginal = (await vi.importActual<any>("bcryptjs")).hash;
(genSalt as Mock).mockImplementationOnce(genSaltOriginal);
(hash as Mock).mockImplementationOnce(hashOriginal);
await createUser(req as Request, res as Response, fakeNext as NextFunction);
This does not work, when I log the salt and hashed password values they return undefined, and for some reason when I comment out (hash as Mock).mockImplementationOnce(hashOriginal)
the genSalt
works and returns an actual salt when I log it to the console, but enabling this line breaks it, also here is the code for hash generation:
let salt;
let hashedPassword;
try {
salt = await genSalt(10);
hashedPassword = await hash(password, salt);
} catch (err) {
next(new CustomError(undefined, 500, `Password hashing failed\n${err}`));
return;
}
Share
Improve this question
edited Feb 5 at 7:33
funnyVariable
asked Feb 3 at 23:35
funnyVariablefunnyVariable
151 silver badge5 bronze badges
1 Answer
Reset to default 0I managed to fix it, I just invoked the original functions inside the test, then mocked genSalt
and hash
with the results.
const genSaltOriginal = (await vi.importActual<any>("bcryptjs")).genSalt;
const hashOriginal = (await vi.importActual<any>("bcryptjs")).hash;
const salt = await genSaltOriginal(10);
const hashedPassword = await hashOriginal(password, salt);
(genSalt as Mock).mockResolvedValueOnce(salt);
(hash as Mock).mockResolvedValueOnce(hashedPassword);