您正在尝试在nodejs中拆除Jest环境后`import`文件

lstz6jyr  于 2023-09-28  发布在  Jest
关注(0)|答案(1)|浏览(98)

我正在为node项目中的一个类编写单元测试。我已经阅读了其他线程的人有这个错误,但我不能解决这个问题,按照他们的指示。所以,每当我使用命令“npm run test”时,我都会收到以下消息:

ReferenceError: You are trying to `import` a file after the Jest environment has been torn down. From __tests__/calendar/calendarEvents.test.ts.

这是我的测试代码:

import { PreorderController } from '../../src/classes/libraryofthings/PreorderController';
import { MongoServer } from './db/MongoServer';
import { afterAll, beforeAll, describe, expect, jest, test } from '@jest/globals';

describe('jest testing', () => {
    let mongoServer;
    beforeAll(async () => {
        mongoServer = new MongoServer();
        await mongoServer.start();
    })
    afterAll(async () => {
        await mongoServer.stop();
    })
    test('it saves a new preorder using the preorder controller class', () => {
        const controller = new PreorderController();
    })
})

我没有做任何花哨的事情,因为我试图在这里调试这个错误。这就是为什么在测试用例中看不到任何expect。这是类的代码:

import { PreorderCreated } from "../../models/events/LibOfThings/Preorders";
import Preorder, { PreorderCreated as PreorderCreatedMongo } from "../../models/mongodb/Calendar/Preorder";
import { AvailableEvents, PossibleStatuses } from "../../types/calendar";
import { Web3Controller } from "../web3/Web3Controller";
import { PreroderInDB } from "./Preorder";

export class PreorderController {
    private web3Controller: Web3Controller;
    private timeout: number;
    private possibleStatuses: PossibleStatuses = {
        pending: 'Pending',
        cancelled: 'Cancelled',
        denied: 'Denied',
        accepted: 'Accepted',
        ended: 'Ended',
        started: 'Started'
    }
    private availableEvents: AvailableEvents = {
        preorderCreated: 'PreorderCreated',
        preorderAccepted: 'PreorderAccepted',
        preorderCancelled: 'PreorderCancelled',
        preorderDenied: 'PreorderDenied',
        preorderStarted: 'PreorderStarted',
        preorderEnded: 'PreorderEnded',
    }

    constructor() {
        this.timeout = 1000;
        this.web3Controller = new Web3Controller();
    }

    async getPreorder(id: string): Promise<PreorderCreatedMongo> {
        return await Preorder.findOne({ preorderID: id });
    }

    async savePreorderInMongo(preorderCreatedObj: PreorderCreated, timestamp: number, userInfo: {
        lenderAddressInfo: string,
        borrowerAddressInfo: string
    }, address: string, realm: string): Promise<void> {
        try {
            console.log(`Handle preorder created: ${new Date()}`);
            const preorder = await Preorder.findOne({ preorderID: preorderCreatedObj._preorderID });
            if (preorder == null) {
                console.log(`New preorder data = ${JSON.stringify(preorderCreatedObj)} with ID: ${preorderCreatedObj._preorderID}`);
                console.log(`Preorder is null, adding its document in the colleciton "Preorder"`)
                await Preorder.create({
                    "preorderID": preorderCreatedObj._preorderID,
                    "itemID": preorderCreatedObj._idItem,
                    "startDate": preorderCreatedObj._startDate,
                    "endDate": preorderCreatedObj._endDate,
                    "timestamp": timestamp,
                    "lender": preorderCreatedObj._lender,
                    "status": this.possibleStatuses.pending,
                    "borrower": preorderCreatedObj._borrower,
                    "contractAddress": address,
                    "realm": realm,
                    "lenderFSName": userInfo.lenderAddressInfo,
                    "borrowerFSName": userInfo.borrowerAddressInfo,
                    "itemName": preorderCreatedObj._itemName
                })
            } else {
                console.log(`Preorder with ID = ${preorderCreatedObj._preorderID} already exists in 'preorders' collection`);
            }
        } catch (error) {
            console.log(error);
        }
    }

    async updateStatus(id: string, newStatus: string, blockNumber: number): Promise<void>
    async updateStatus(id: string, newStatus: string, blockNumber: number, comment: string): Promise<void>
    async updateStatus(id: string, newStatus: string, blockNumber: number, comment: string, itemWasFine: boolean): Promise<void>
    async updateStatus(id: string, newStatus: string, blockNumber: number, comment?: string, itemWasFine?: boolean): Promise<void> {
        const timestamp = await this.web3Controller.getBlockTimestamp(blockNumber);

        const preorder = await this.getPreorder(id);
        if (!preorder) {
            await sleep(this.timeout);
            return this.updateStatus(id, newStatus, blockNumber, comment, itemWasFine);
        } else {
            if ((timestamp as Number) > preorder.timestamp) {
                const preorderInstance = new PreroderInDB(newStatus, id);
                await preorderInstance.updateStatus(newStatus, timestamp);
                if (newStatus === this.possibleStatuses.ended)
                    await preorderInstance.addReviewInfoToPreorder(comment, itemWasFine);
            }
        }
    }

    getPreorderStatusAssociatedWithEvent(eventType: string): string {
        let status: string;

        switch (eventType) {
            case this.availableEvents.preorderCreated:
                status = this.possibleStatuses.pending;
                break;
            case this.availableEvents.preorderAccepted:
                status = this.possibleStatuses.accepted;
                break;
            case this.availableEvents.preorderCancelled:
                status = this.possibleStatuses.cancelled;
                break;
            case this.availableEvents.preorderDenied:
                status = this.possibleStatuses.denied;
                break;
            case this.availableEvents.preorderStarted:
                status = this.possibleStatuses.started;
                break;
            case this.availableEvents.preorderEnded:
                status = this.possibleStatuses.ended;
                break;
            default:
                throw new Error(`I don\'t know what to do with this event type: ${eventType}`);
        }

        return status;
    }

    getPreorderAvailableStautuses(): PossibleStatuses {
        return this.possibleStatuses;
    }

    getAvailableEvents(): AvailableEvents {
        return this.availableEvents;
    }

    eventPreorderCreatedReceived(eventName: string): boolean {
        return eventName === this.availableEvents.preorderCreated;
    }

    eventPreorderEndedReceived(eventName: string): boolean {
        return eventName === this.availableEvents.preorderEnded;
    }
}

const sleep = (ms: number) => {
    return new Promise((resolve) => setTimeout(resolve, ms));
}

我认为这与我的自定义sleep()函数中的setTimeout函数有关,但我无法弄清楚。

iezvtpos

iezvtpos1#

您需要在测试文件中的import语句之后(但在describe之前)添加以下语句:__tests__/calendar/calendarEvents.test.ts

jest.useFakeTimers()

jest使用它来模拟您在PreorderController中使用的setTimeout
本机定时器函数(即,setTimeout()、setInterval()、clearTimeout()、clearInterval())对于测试环境来说不太理想,因为它们依赖于真实的时间的流逝。Jest可以将计时器与允许您控制时间流逝的函数交换。
https://jestjs.io/docs/timer-mocks

相关问题