ReferenceError:初始化之前无法访问“ mockMethod1”

时间:2020-07-03 09:21:31

标签: javascript typescript unit-testing jestjs

我有3个源文件File1.ts,File2.ts,File3.ts。在执行File3的单元测试时,出现以下错误。

Test suite failed to run

    ReferenceError: Cannot access 'mockMethod1' before initialization

      20 |     __esModule: true,
      21 |     default: jest.fn(),
    > 22 |     method1: mockMethod1,
         |              ^
      23 |     method2: mockMethod2
      24 | }));
      25 | 

以下是3个源文件的内容以及File3的单元测试。

File1.ts

export default class File1 {
    public element;

    constructor(element) {
        this.element = element;
    }

     method1(inputs) {
         // Logic of Method1.
         return output;
     }

     method2(inputs) {
         // Logic of Method2.
         return output;
     }
}

File2.ts

import File1 from '../Folder1/File1'

export default class File2 {
    public file1Object;

    constructor(element) {
        this.file1Object = new File1(element);
    }

     method1(inputs) {
         // Logic of Method1.
         let out = this.file1Object.method1(inputs);
         // Logic of Method1.
         return output;
     }

     method2(inputs) {
         // Logic of Method2.
         let out = this.file1Object.method2(inputs);
         // Logic of Method2.
         return output;
     }
}

File3.ts

import File2 from '../Folder2/File2'
export default class File3 {
    public file2Object;

    constructor(element) {
        this.file2Object = new File2(element);
    }

     method1(inputs) {
         // Logic of Method1.
         let out = this.file2Object.method1(inputs);
         // Logic of Method1.
         return output;
     }

     method2(inputs) {
         // Logic of Method2.
         let out = this.file2Object.method1(inputs);
         // Logic of Method2.
         return output;
     }
}

File3.test.ts

import File3 from "./File3";
import File2 from "../Folder2/File2";

const mockMethod1 = jest.fn();
const mockMethod2 = jest.fn();

jest.mock('../Folder2/File2', () => ({
    __esModule: true,
    default: jest.fn(),
    method1: mockMethod1,
    method2: mockMethod2
}));

const file3Object = new File3(inputElement);
beforeEach(() => {
    jest.clearAllMocks();
});

test('Method-1 Unit Test', () => {
    mockMethod1.mockReturnValue(expectedOutput);
    let observedOutput = file3Object.method1(inputs);

    expect(observedOutput).toBe(expectedOutput);
})

test('Method-2 Unit Test', () => {
     mockMethod2.mockReturnValue(expectedOutput);
    let observedOutput = file3Object.method2(inputs);
     
     expect(observedOutput).toBe(expectedOutput);
})

我不确定我在哪里出错,因此无法解决此错误。任何解决此问题的建议。

1 个答案:

答案 0 :(得分:4)

有几件事引起麻烦。首先,如jest docs中所述:

factory参数的局限性在于,由于对jest.mock()的调用被提升到文件的顶部,因此无法先定义变量然后在工厂中使用它。以'mock'开头的变量例外。 由您保证可以按时初始化它们!

这意味着您需要在代码行之间移动以使它们看起来像这样:

  // First the mock functions
  const mockMethod1 = jest.fn();
  const mockMethod2 = jest.fn();
  
  // Only then your imports & jest.mock calls
  import File3 from "./File3";
  import File2 from "../Folder2/File2";

  jest.mock('../Folder2/File2', () => ({
    // ...
  }));

第二个问题是,您正在嘲笑File2,就好像它正在导出method1method2一样,您不是在嘲笑method1method2File2类!看看4 ways of mocking an ES6 class in jest docs