Не удалось запустить набор тестов / jest.mock()

#typescript #unit-testing #jestjs #mocking #ts-jest

#typescript #модульное тестирование #jestjs #издевательство #ts-jest

Вопрос:

Изначально клиентская сторона (TypeScript) нашего веб-приложения не писала код модульного тестирования. На этот раз воссоздаются только входные части существующих экранов. Мы добавляем новые компоненты ввода и переключаем существующие экраны на использование новых компонентов ввода. Впервые мы планируем написать модульный тестовый код и провести модульные тесты для недавно добавленных новых классов входных компонентов.

Существующие классы экрана (до введения Jest) были реализованы классами с пространством имен следующим образом. [с пространством имен (aaa.bbb.ccc.~), не экспортировать пространство имен, экспортировать класс, импортировать класс (указанное пространство имен)]

 // Entry1.ts : The existing screen class
module aaa.bbb.ccc.ddd.eee {
    import AlertDialog = aaa.bbb.ccc.overlaycomponent.AlertDialog;
    export class Entry1 {
        private alertDialog: AlertDialog;
    }
}
 

Поскольку модульное тестирование не может быть выполнено с помощью Jest в приведенной выше реализации, для недавно добавленных классов входных компонентов используется следующая реализация, которая выполняет модульное тестирование с помощью Jest.
[с пространством имен (aaa.bbb.ccc.~), пространством имен экспорта, классом экспорта, пространством имен импорта (указанный путь к файлу)]

 // zGrid.ts : The newly added input component class 1
import { aaa as aaa1 } from './zRow';
import ZRow = aaa1.bbb.ccc.controls.zGrid.ZRow;

export module aaa.bbb.ccc.controls.zGrid {
    /** Zeta Grid */
    export class ZGrid {
        private rows: ZRow[];
        constructor() {
            this.rows = [new ZRow(), new ZRow(), new ZRow()];
        }
        public getCount(): number {
            let total: number = 0;
            this.rows.forEach((value: ZRow, index: number, array: ZRow[]) => {
                total  = value.getColCount();
            }, this);
            return total;
        }
    }
}
 
 // zRow.ts : The newly added input component class 2
import { aaa as aaa1 } from './zColumn';
import ZColumn = aaa1.bbb.ccc.controls.zGrid.ZColumn;

export module aaa.bbb.ccc.controls.zGrid {
    /** Zeta Grid Row */
    export class ZRow {
        private cols: ZColumn[];
        constructor() {
            this.cols = [new ZColumn(), new ZColumn()];
        }
        public getColCount(): number {
            return this.cols.length;
        }
    }
}
 

Вопрос 1

Модульный тестовый код (без макета) работает нормально.

 // zGrid.test.ts : (for the newly added input component class 1 : zGrid.ts)
import { mocked } from 'ts-jest/utils';

import { aaa as aaa1 } from './zGrid';
import ZGrid = aaa1.bbb.ccc.controls.zGrid.ZGrid;
import { aaa as aaa2 } from './zRow';
import ZRow  = aaa2.bbb.ccc.controls.zGrid.ZRow;

describe("case1", () => {
    it("pat1", () => {
        let grid = new ZGrid();
        expect(grid.getCount()).toBe(6);
    });
});
 

Unit test code (with Mock) works too. (Test suite ran.)

 // zGrid.test.ts : (for the newly added input component class 1 : zGrid.ts)
import { mocked } from 'ts-jest/utils';

import { aaa as aaa1 } from './zGrid';
import ZGrid = aaa1.bbb.ccc.controls.zGrid.ZGrid;
import { aaa as aaa2 } from './zRow';
import ZRow  = aaa2.bbb.ccc.controls.zGrid.ZRow;

jest.mock('./zRow'); // diff

describe("case1", () => {
    it("pat1", () => {
        let grid = new ZGrid();
        expect(grid.getCount()).toBe(6);
    });
});
 

But, Unit test code (with Mock) got fail. What’s Going on?

 // zGrid.test.ts : (for the newly added input component class 1 : zGrid.ts)
import { mocked } from 'ts-jest/utils';

import { aaa as aaa1 } from './zGrid';
import ZGrid = aaa1.bbb.ccc.controls.zGrid.ZGrid;
import { aaa as aaa2 } from './zRow';
import ZRow  = aaa2.bbb.ccc.controls.zGrid.ZRow;

// diff (begin)
jest.mock('./zRow', () => {
    return {
        ZRow: jest.fn().mockImplementation(() => {
            return {
                getColCount: () => { return 1 },
            };
        })
    };
});
// diff (end)

describe("case1", () => {
    it("pat1", () => {
        let grid = new ZGrid();
        expect(grid.getCount()).toBe(3);
    });
});
 

Сбой вывода

 >yarn jest zGrid.test.ts
yarn run v1.22.5
$ C:zzzScriptsnode_modules.binjest zGrid.test.ts
 FAIL  yyy/controls/zGrid.test.ts
   Test suite failed to run

    TypeError: Cannot read property 'bbb' of undefined

      1 | import { aaa as aaa1 } from './zRow';
    > 2 | import ZRow = aaa1.bbb.ccc.controls.zGrid.ZRow;
        |                    ^
      3 |
      4 | export module aaa.bbb.ccc.controls.zGrid {
      5 |     /** Zeta Grid */

      at yyy/controls/zGrid.ts:2:20
      at yyy/controls/zGrid.js:3:17
      at Object.<anonymous> (yyy/controls/zGrid.js:9:3)
      at Object.<anonymous> (yyy/controls/zGrid.test.ts:3:1)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        10.919 s
Ran all test suites matching /zGrid.test.ts/i.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
 

Вопрос 2

Мы хотим использовать класс ZGrid(zGrid.ts) в классе Entry1 (Entry1.ts), но мы не можем найти «Как импортировать класс ZGrid в класс Entry1». Гибридная реализация с src-кодом «Export namespace amp; class» (zGrid.ts) и src-кодом «Export class» (Entry1.ts) невозможна?

Среда разработки выглядит следующим образом.

  • Windows 10
  • Visual Studio версии 2017 или 2019
  • TypeScript версия 2.9.2
  • Jest ver.26.6
  • ts-jest версия.26.4.4
  • Yarn версия 1.22.5
  • Node.js вер.12.18.4

Ответ №1:

Вопрос 1

Я нашел ответ.

 // zGrid.test.ts : (for the newly added input component class 1 : zGrid.ts)
import { mocked } from 'ts-jest/utils';

import { aaa as aaa1 } from './zGrid';
import ZGrid = aaa1.bbb.ccc.controls.zGrid.ZGrid;
import { aaa as aaa2 } from './zRow';
import ZRow  = aaa2.bbb.ccc.controls.zGrid.ZRow;

// diff (begin)
jest.mock('./zRow', () => {
    return {
        aaa: { // Added!
            bbb: { // Added!
                ccc: { // Added!
                    controls: { // Added!
                        zGrid: { // Added!
                            ZRow: jest.fn().mockImplementation(() => {
                                return {
                                    getColCount: () => { return 1 },
                                };
                            })
                        } // Added!
                    } // Added!
                } // Added!
            } // Added!
        } // Added!
    };
});
// diff (end)

describe("case1", () => {
    it("pat1", () => {
        let grid = new ZGrid();
        expect(grid.getCount()).toBe(3);
    });
});
 

Комментарии:

1. Вопрос 2. Гибридная реализация с src-кодом «Export namespace amp; class» (zGrid.ts) и src-кодом «Export class» (Entry1.ts), возможно, невозможна.