Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deno mock out named import in unit test

I would like to make an unit test for a module that is using jsonfile to read the data.

import * as jsonfile from 'https://deno.land/x/jsonfile/mod.ts'

would like to mock out the jsonfile.readJsonSync to return the test data and avoid writing to disk. Can this be done?

Hope this abstract example describes what I want to archive:

index.ts

import * as jsonfile from 'https://deno.land/x/jsonfile/mod.ts'

export function readAndReturn() {
  return jsonfile.readJsonSync('./example.json')
}

index.test.ts

import { assertEquals } from 'https://deno.land/[email protected]/testing/asserts.ts'
import { readAndReturn } from './index.ts'


const dataFixture = {hello: "word"} 
// mock out jsonfile.readJsonSync to return dataFixture and not the actual file content

Deno.test("Reads the data", () => {
  assertEquals(readAndReturn(), dataFixture)
})

Solution

A huge thanks to @mfulton26 and @jsejcksn for pointing me in the right direction.

unit.test.importmap.json

{
  "imports": {
    "https://deno.land/x/jsonfile/mod.ts": "./mocks/jsonfile.ts"
  }
}

mocks/jsonfile.ts

import sinon from 'https://cdn.skypack.dev/[email protected]?dts'

const readJsonSync = sinon.stub()
const writeJsonSync = sinon.stub()

export { readJsonSync, writeJsonSync }

index.test.ts

import { readJsonSync as readJsonSyncMock } from './mocks/jsonfile.ts'

Deno.test(
  'Reads the data', () => {
    const data = ["hello world"]
    readJsonSyncMock.withArgs(`./example.json`).returns(data)
    assertEquals(readAndReturn(), data)
  }
)

deno test --import-map=unit.test.importmap.json
like image 954
Norfeldt Avatar asked Oct 23 '25 07:10

Norfeldt


2 Answers

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
like image 171
jsejcksn Avatar answered Oct 25 '25 07:10

jsejcksn


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.

like image 44
mfulton26 Avatar answered Oct 25 '25 07:10

mfulton26



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!