#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), возможно, невозможна.