unstable_mockModule 不嘲笑 ESM - 开玩笑

问题描述 投票:0回答:1

我在我的项目中使用ESM。我所有的

.ts
文件都被转换为存储在“dist”文件夹中的
.js
。我的目录结构的示例布局是:

dist/
├─ src/
│  ├─ store/
│  │  ├─ index.js
│  ├─ strategies/
│  │  ├─ scalping/
│  │  │  ├─ main.js 
src/
├─ store/
│  │  ├─ index.ts
├─ strategies/
│  │  ├─ scalping/
│  │  │  ├─ main.ts 
test/
├─ strategies/
│  │  ├─ scalping/
│  │  │  ├─ main.test.ts 

我的 tsconfig.json 中的

moduleResolution
是“NodeNext”

我的

jest.config.ts
是:

import type { Config } from "jest"

const config: Config = {
    preset: 'ts-jest/presets/default-esm',
    displayName: "scalper",
    testTimeout: 60000, // 30 secs - Necessary for when testing timers
    globalSetup: "<rootDir>/test/jest/setup.ts",
    globalTeardown: "<rootDir>/test/jest/teardown.ts",
    coveragePathIgnorePatterns: [ "/node_modules/" ],
    testMatch: ["<rootDir>/test/**/?(*.)+(spec|test).[jt]s?(x)"],
    modulePathIgnorePatterns: ["<rootDir>/test/.*/__mocks__", "<rootDir>/dist/"],
    testEnvironment: "node",
    coverageDirectory: "<rootDir>/coverage",
    extensionsToTreatAsEsm: [".ts"],
    moduleNameMapper: {
        "^(.*)\\.js$": "$1",
    },
    transform: {
        '^.+\\.ts?$': [
            'ts-jest',
            {
                useESM: true
            }
        ]
    },
}

export default config

我的

test/main/index.test.ts
是:

import { jest } from '@jest/globals'
import * as fs from "fs"
import * as path from "path"
import appRoot from "app-root-path"

const params = JSON.parse(fs.readFileSync(path.join(appRoot.path, 'test/strategies/scalping/main/params.json'), 'utf8'))

import * as strategies from "../../../../src/strategies/scalping/index.js"

describe('main', () => {
    it('Should create a valid scalp trade', async () => {
        const { builtMarket, config } = params

        // Mocking of ESM requires dynamic imports
        // https://jestjs.io/docs/ecmascript-modules#module-mocking-in-esm
        jest.unstable_mockModule('../../../../src/store/index.js', () => ({
            getScalpRunners: jest.fn().mockResolvedValue(params as never)
        }))

        const store = await import('../../../../src/store/index.js')

        await strategies.scalping(builtMarket, config)
    })
})

方法

getScalpRunners
我本以为会被嘲笑,但它不是&调用主要定义。我查看了以下模拟 ESM 模块的文档(在代码中链接)并且我查看了这个问题,但它仍然不起作用。

我的

src/strategies/scalping/main.ts
的一个片段是:

import store from "../../store/index.js"

export default async function(builtMarket: BuiltMarket, config: Config): Promise<BuiltMarket | undefined> {
    try {
        const validMarket = isValidMarket(builtMarket, config)

        if (validMarket) {
            const polledRunners: ScalpRunner[] | undefined = await store.getScalpRunners({
                eventId: builtMarket._eventId,
                marketId: builtMarket._marketId
            })

            // other stuff...
        }
    } catch(err: any) {
        throw err
    }
}

为什么这没有被正确地嘲笑?

编辑:

如果我在

store
中输出
index.test.ts
的值,那么它就是模块的模拟版本。然而,在
main.ts
中,它是模块的未模拟版本。

typescript jestjs mocking es6-modules ts-jest
1个回答
0
投票

我解决了这个问题,但看起来很混乱。我将

../../../../src/strategies/scalping/index.js
的导入更改为动态导入而不是静态导入,以确保它使用的是模拟导入,并且必须模拟
store/index.js
的默认导出。

index.test.ts

// Not usually required to import global but apparently the use of ESM does need it
// https://jestjs.io/docs/ecmascript-modules#differences-between-esm-and-commonjs
import { jest } from '@jest/globals'

// Mocking of ESM requires dynamic imports
// https://jestjs.io/docs/ecmascript-modules#module-mocking-in-esm
jest.unstable_mockModule('../../../../src/store/index.js', () => ({
    default: {
        getScalpRunners: jest.fn().mockResolvedValue(params as never)
    }
}))

import * as fs from "fs"
import * as path from "path"
import appRoot from "app-root-path"

const params = JSON.parse(fs.readFileSync(path.join(appRoot.path, 'test/strategies/scalping/main/params.json'), 'utf8'))

// Mocking of ESM requires dynamic imports
// This ensures that the import is done AFTER the mock
const store = await import('../../../../src/store/index.js')
const strategies = await import('../../../../src/strategies/scalping/index.js')

describe('main', () => {
    it('Should create a valid scalp trade', async () => {
        const { builtMarket, config } = params

        await strategies.scalping(builtMarket, config)
    })
})
© www.soinside.com 2019 - 2024. All rights reserved.