Just as a programming language can be considered a virtual computer, that is, a computer implemented in software, so a computer can be considered a programming language implemented in hardware.
Maclennon, Principles of Programming Languages
There are many ways to import modules with ESM. Some ways allow for testing frameworks to intercept and mock methods from these modules, while others do not.
Two methods I use most often are:
// named imports (destructured into method names}
import { fnUsedAsReal, fnToBeMocked } from "file.ts";
and
// namespace import (or star-import)
import * as File1Module from "./file.ts";
Namespace imports are required for vitest to be able to spy/mock dynamically.
vi.spyOn(File1Module, "fnToBeMocked").mockResolvedValue(["123123", "123124", "123125"]);
The biggest gotcha I’ve found in upgrading from jest to vitest is that if any of the mocked methods are called internally within its own module, the mock does not work. e.g.
You have a test in file.test.ts.
It imports all methods from file.service.ts -> import * as MyService from 'file.service.ts';
You mock a method function1 so you can test it… but inside file.service.ts
there are references/calls to function1, the mock will not work.
The workaround is simply to move anything that has to be mocked to its own file.
iow for the example above, both the test file and the service file will import
function1 from a third file, and the mock will work. This, in my case, is
mostly fine as the internal calls are almost all to database functions that make
sense to be organized into their own file anyway.