Deno mock out named import in unit test

You can substitute modules using an import map.

Just create a local module ./jsonfile.mock.ts containing your mocked functions and export them using the same names as the real module at https://deno.land/x/jsonfile/mod.ts. Then, create an import map with the correct mapping and use it when you run your test:

./jsonfile.mock.ts:

export function readJsonSync (filePath: string): unknown {
  // implement mocked fn
}

// and any other imports you use from the module

./index.importmap.json:

{
  "imports": {
    "https://deno.land/x/jsonfile/mod.ts": "./jsonfile.mock.ts"
  }
}
deno test --import-map=index.importmap.json index.test.ts

ES modules cannot be stubbed.

You can however wrap the functionality you want to stub in a class or object and export that and then you can stub methods on it using Sinon.JS or other libraries.

For getting started with Sinon.JS in Deno I suggest checking out Integration with testing libraries | Testing | Manual | Deno which references a sinon_example.ts.


Wrapping your module with another module might work in some cases, but if your module has side effects with errors in them, this won't work.

I've created a small module to get around this issue: Fake Imports.

It might not be possible to mock static imports, but dynamic imports certainly can be mocked!

Usage

import { Importer } from "https://deno.land/x/fake_imports/mod.js";
const importer = new Importer(import.meta.url);

importer.fakeModule("https://deno.land/x/jsonfile/mod.ts", `
function readJsonSync() {}
export {readJsonSync};
`);

// Then load your main module asynchronously
const mainModule = await importer.import("./main.ts");
// And perform your test on mainModule like you usually would