aelbore / esbuild-jest

A Jest transformer using esbuild
519 stars 51 forks source link

Error using the function `mockDeep<PrismaClient>()` from `jest-mock-extended` with `esbuild-jest` #73

Open joaocasarin opened 2 years ago

joaocasarin commented 2 years ago

Well, the error is pretty auto-describable.

To perform unit tests with Prisma, we need to mock the PrismaClient, and for that we use the package jest-mock-extended and its method mockDeep over PrismaClient. However, if I want to use the transformer esbuild-jest instead of the traditional ts-jest, it fails exactly on the line where mockDeep<PrismaClient>() is called.

Packages versions:

"devDependencies": {
    "@types/jest": "^27.5.0",
    "@types/node": "^17.0.31",
    "@types/uuid": "^8.3.4",
    "esbuild": "^0.14.38",
    "esbuild-jest": "^0.5.0",
    "jest": "^28.1.0",
    "jest-mock-extended": "^2.0.5",
    "prisma": "^3.13.0",
    "ts-jest": "^28.0.1",
    "ts-node-dev": "^1.1.8",
    "typescript": "^4.6.4"
  },
  "dependencies": {
    "@prisma/client": "^3.13.0"
  }

Repository to reproduce the error: fail_esbuild-jest_with_prisma

Steps to reproduce:

1. Install dependencies

$ yarn install

2. Run tests using ts-jest

$ yarn ts:test

3. Run tests using esbuild-jest

$ yarn esbuild:test

Expected results

Both should succeed and show the following output:

 PASS  tests/CreateUser.test.ts
  √ should create an user (3 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        2.043 s
Ran all test suites.
Done in 2.99s.

Current results with esbuild-jest

However, the second one - esbuild:test is failing with the following output:

 FAIL  tests/CreateUser.test.ts
  ● Test suite failed to run

    Jest encountered an unexpected token

    Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.

    Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.

    By default "node_modules" folder is ignored by transformers.

    Here's what you can do:
     • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
     • If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.    

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/configuration
    For information about custom transformations, see:
    https://jestjs.io/docs/code-transformation

    Details:

    SyntaxError: C:\Users\joaov\Desktop\fail_esbuild-jest_with_prisma\src\db\singleton.ts: Cannot transform the imported binding "PrismaClient" since it's also used in a type annotation. Please strip type annotations using @babel/preset-typescript or @babel/preset-flow.
       6 | jest.mock('./client', () => ({
       7 |     __esModule: true,
    >  8 |     default: mockDeep<PrismaClient>()
         |                       ^^^^^^^^^^^^
       9 | }));
      10 | const prismaMock = prisma as unknown as DeepMockProxy<PrismaClient>;
      11 | beforeEach(() => {

      at File.buildCodeFrameError (node_modules/@babel/core/lib/transformation/file/file.js:249:12)
      at NodePath.buildCodeFrameError (node_modules/@babel/traverse/lib/path/index.js:143:21)
      at Object.ReferencedIdentifier (node_modules/@babel/helper-module-transforms/lib/rewrite-live-references.js:201:20)
      at Object.newFn (node_modules/@babel/traverse/lib/visitors.js:218:17)
      at NodePath._call (node_modules/@babel/traverse/lib/path/context.js:53:20)
      at NodePath.call (node_modules/@babel/traverse/lib/path/context.js:40:17)
      at NodePath.visit (node_modules/@babel/traverse/lib/path/context.js:100:31)
      at TraversalContext.visitQueue (node_modules/@babel/traverse/lib/context.js:103:16)
      at TraversalContext.visitSingle (node_modules/@babel/traverse/lib/context.js:77:19)
      at TraversalContext.visit (node_modules/@babel/traverse/lib/context.js:131:19)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        0.494 s
Ran all test suites.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
sambs commented 2 years ago

Have you found a solution to this? I'm also facing this problem.

joaocasarin commented 2 years ago

Hi @sambs sorry not answering this earlier, I know it's been months but I have stopped working on my project using esbuild and esbuild-jest, but I just started it again and I hope someone can help us. Unfortunately I haven't found a solution for this yet, it seems to be a real issue with esbuil-jest.

Apparently no one answered this issue and no other new issues were raised, but would you or any other contributor mind helping us please? @aelbore

nfroidure commented 2 years ago

I think the problem sits with Jest itself that has not finished its migration to ESM yet. You can follow the progress here: https://github.com/facebook/jest/issues/9430

Hopefully, Jest will switch to esbuild deprecating this module since nowaday, babel is probably a bit overkill for modern development and damn slow after tasting esbuild ;).

joaocasarin commented 2 years ago

I think the problem sits with Jest itself that has not finished its migration to ESM yet. You can follow the progress here: https://github.com/facebook/jest/issues/9430

Hopefully, Jest will switch to esbuild deprecating this module since nowaday, babel is probably a bit overkill for modern development and damn slow after tasting esbuild ;).

But if it were a problem with jest itself, then @swc/jest shouldn't be able to run the testing using that config, right?

nfroidure commented 2 years ago

@joaocasarin it is due to this : https://github.com/aelbore/esbuild-jest/issues/54

Once a jest.mock is detected, it fallbacks to using Babel which leads to syntax errors.