Невозможно смоделировать модуль узла с помощью JEST (с Typescript) и среды React - PullRequest
0 голосов
/ 10 июля 2020

Я сделал библиотеку перехватчиков React, доступную на NPM.

Для модульного тестирования этой библиотеки я использую JEST с Typescript.

Он имеет зависимость с другим модулем узла @brand/dependencyModule.

Этот @brand/dependencyModule выполняет HTTP-запрос и генерирует события (с { EventEmitter } from 'events'), которые мне нужно имитировать.

Я пытался следовать документации JEST , чтобы вручную смоделировать эту библиотеку.

Во-первых, позвольте мне показать вам, что я пробовал:

  1. Создать папку __mocks__ на уровне проекта root (на том же уровне, что и node_modules)
  2. Создать подпапку @brand внутри __mocks__
  3. Создать файл TS dependencyModule.ts внутри @brand папку

Внутри __mocks__/@brand/dependencyModule.ts, у нас есть:

'use strict';

import { EventEmitter } from 'events';
import {
    SomeTyping
} from '@brand/dependencyModule';

class MockVisitor extends EventEmitter {
    someAttribute1: string;

    someAttribute2: string;

    someAttribute3: SomeTyping;

    constructor(some) {
        super();
        this.someAttribute1 = some;
        this.someAttribute2 = parameter;
        this.someAttribute3 = mockHttpResponse;

        setTimeout(() => {
            this.emit('ready');
        }, 100);
    }
}

class MockModule {
    otherAttribute1: string;

    constructor(otherParam) {
        this.otherAttribute1 = otherParam;
    }

    public newVisitor(some, param) {
        return new MockVisitor(some, param);
    }
}

export default jest.fn().mockImplementation(() => ({
    start: (someStuff) => {
        return new MockModule(someStuff);
    }
}));

Теперь в моем файле src/**/index.test.ts у меня есть:


describe('trying to mock @brand/dependencyModule', () => {
    test('it should use the mock version', async () => {
        let isReady = null;
        const { container } = render(
            <MyHookProvider
                onInitDone={() => {
                    isReady = true;
                }}
            >
                <div>Hello</div>
            </MyHookProvider>
        );

        await waitFor(() => {
            if (!isReady) {
                throw new Error('not ready');
            }
        });
        expect(isReady).toEqual(true);
    });
});

Наконец, давайте посмотрим на файл MyHookProvider.tsx, в котором используется '@ brand / dependencyModule ':

import React, { useState, useEffect, SetStateAction, Dispatch, useContext } from 'react';

import dependencyModule from '@brand/dependencyModule';


export const MyHookProvider: React.SFC</*...*/> = ({
    // ...
    onInitDone,
}: ProviderProps) => {
    useEffect(() => {
        const module = dependencyModule.start('hello');
        const visitorInstance = module.newVisitor('stack','overflow');
        
        visitorInstance.on('ready', () => {
            onInitDone()
        });
    }, [/*...*/]);

    return (
        <MyHook.Provider value={{ ... }}>
                {"I'm ready."}
        </MyHook.Provider>
    );
};

MyHookProvider.defaultProps = {
    onInitDone: (): void => {
        // do nothing
    },
};


Теперь ошибка, возникающая при запуске npm run test, я ожидаю, что шутка обнаружит, что я издевался над @brand/dependencyModule, но когда я отлаживаю, он фактически запускает настоящую библиотеку. Я не знаю, чего мне не хватает, чтобы это работало.

Есть помощь? Спасибо!

Вот библиотеки, которые я использую для модульного тестирования:

        "@testing-library/jest-dom": "^5.5.0",
        "@types/jest": "^25.2.1",
        "@types/enzyme": "^3.10.5",
        "@types/enzyme-adapter-react-16": "^1.0.6",
        "enzyme": "^3.11.0",
        "enzyme-adapter-react-16": "^1.15.2",
        "enzyme-to-json": "^3.4.4",
        "jest": "^25.4.0",
        "jest-mock-axios": "^3.2.0",
        "ts-jest": "^25.4.0",

jest config setup как это:

    "jest": {
        "setupFilesAfterEnv": [
            "./src/setupTests.js"
        ]
    }

with src/setupTests.js:

import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

configure({ adapter: new Adapter() });
...