测试套件无法运行 / jest.mock()

时间:2020-12-29 08:15:40

标签: typescript unit-testing jestjs mocking ts-jest

最初,我们的 Web 应用程序的客户端 (TypeScript) 没有编写单元测试代码。这一次,现在只重新创建现有屏幕的输入部分。我们正在添加新的输入组件并切换现有屏幕以使用新的输入组件。 第一次,我们计划编写单元测试代码,并对新增的输入组件类进行单元测试。

现有的屏幕类(在引入 Jest 之前)由具有命名空间的类实现,如下所示。 [with namespace(aaa.bbb.ccc.~),不导出namespace,导出类,导入类(指定的namespace)]

// 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进行单元测试的输入组件类,采用以下实现。 [with namespace(aaa.bbb.ccc.~), export namespace, export class, import namespace(指定文件路径)]

// 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

单元测试代码(没有 Mock)工作正常。

// 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);
    });
});

单元测试代码(使用 Mock)也能工作。 (测试套件运行。)

// 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);
    });
});

但是,单元测试代码(使用 Mock)失败了。发生什么事了?

// 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:\zzz\Scripts\node_modules\.bin\jest 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

我们想在 Entry1 类(Entry1.ts)中使用 ZGrid 类(zGrid.ts),但是我们找不到“如何在 Entry1 类中导入 ZGrid 类”。 使用“导出命名空间和类”源代码 (zGrid.ts) 和“导出类”源代码 (Entry1.ts) 的混合实现是不可能的?

开发环境如下。

  • Windows 10
  • Visual Studio 2017 或 2019 版
  • TypeScript 2.9.2 版
  • 玩笑 26.6 版
  • ts-jest ver.26.4.4
  • 纱线 1.22.5 版
  • Node.js 12.18.4 版

1 个答案:

答案 0 :(得分:0)

问题 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);
    });
});