juggernautjp / jest-manual-mocks-example

Jest Manual Mocks example

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Jest Manual Mocks example (jest-manual-mocks-example)

This example is explained in Jest Docs's Manual Mocks section, and the source files are downloaded from Jest examples/manual-mocks.

Purpose of this example

As mentioned in the ECMAScript Modules, jest's ECMAScript Modules (ESM) support is experimental.

This example is to find the workaround for Jest ES Module support without Babel, and is related to the following issues:

  1. Meta: Native support for ES Modules #9430
  1. jest.mock does not mock an ES module without Babel #10025

ESM and CommonJS interoperability

file to import (require) file to be imported (required) Static Import Dynamic Import require
ESM ESM OK OK NG
CJS CJS NG NG OK
ESM CJS OK NG NG 1
CJS ESM NG OK NG

ESM (ES Modules), CJS (CommonJS), NG (No Good)

The above table is from the Blog post TypeScript 4.7 と Native Node.js ESM.

How to initialize this example

$ git clone <this repository>
$ npm install
# jest --verbose
$ npm run dev:test
# or jest --silent
$ npm test

My Test Environment

OS: Windows11
Node: v16.15.1
Jest: v28.1.2

Test and Result

test file (tests/) file to be imported (required) Mock PASS/FAIL
file_summarizer.test.js FileSummarizer.cjs node/fs CommonJS Mock (ESM require CommonJS) PASS 2
FileSummarizer.test.js FileSummarizer.js No Mock (ESM import node/fs module) PASS
FileSummarizerCJS.test.js FileSummarizer.cjs No Mock (ESM require CommonJS) PASS
FileSummarizerESM.test.js FileSummarizer.mjs No Mock (ESM import ESM) FAIL 3
user.test.js models/user.mjs No Mock (ESM import ESM) PASS
userMocked.test.js models/user.mjs ESM Mock (ESM import ESM) FAIL 4

Workaround

Babel based Jest examples/manual-mocks example is executable without Babel, after "FileSummarizer.js" is renamed to "FileSummarizer.cjs" and the following modification of "file_summarize.test.js":

// 'use strict';
import { jest } from '@jest/globals';

// Node.js - `module.createRequire(filename)`
// https://nodejs.org/api/module.html#modulecreaterequirefilename
import { createRequire } from 'node:module';
const require = createRequire(import.meta.url);

jest.mock('fs');

Issue 2

 FAIL  __tests__/file_summarizerESM.test.js
  listFilesInDirectorySync
    × includes all files in the directory in the summary (1 ms)

   listFilesInDirectorySync  includes all files in the directory in the summary

    TypeError: fs.setMockFiles is not a function

      16 |     // Set up some mocked out file info before each test
      17 |     const fs = await import('node:fs');
    > 18 |     fs.setMockFiles(MOCK_FILE_INFO);
         |        ^

Issue 3

import('../models/user.mjs') dose not import from 'models/mocks/user.mjs', but import 'models/user.mjs'.

 FAIL  __tests__/userMocked.test.js
  × if user model is mocked (8 ms)

   if user model is mocked

    expect(received).toEqual(expected) // deep equality

    - Expected  - 2
    + Received  + 2

      Object {
    -   "age": 622,
    -   "name": "Mock name",
    +   "age": 26,
    +   "name": "Real name",
      }

      20 |   const user = await import('../models/user.mjs');
      21 |   const expected = { age: 622, name: 'Mock name' };
    > 22 |   expect(user.default.getAuthenticated()).toEqual(expected);
         |                                           ^

syncBuiltinESMExports.cjs

syncBuiltinESMExports.cjs is from Node.js - Modules: node:module API - module.syncBuiltinESMExports()

To execute node syncBuiltinESMExports.cjs outputs nothing.

License

MIT licensed

Facebook has the Copyright of the source code.

Footnote

Footnotes

  1. The table marks "NG", but module.createRequire(filename) enable ESM to require CJS.

  2. explained below "Workaround" section

  3. explained below "Issue 1" section

  4. explained below "Issue 2" section

About

Jest Manual Mocks example

License:MIT License


Languages

Language:JavaScript 100.0%