Reputation: 65
I have 3 source files File1.ts, File2.ts, File3.ts. While executing the Unit tests of File3 I am getting the following Error.
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 |
Here are the contents of the 3 source files and unit tests for 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);
})
I am not sure where I am making the mistake so I am unable to resolve this error. Any suggestions to resolve this issue.
Upvotes: 5
Views: 15921
Reputation: 1926
There are several things that are causing trouble. First, as mentioned in jest docs:
A limitation with the factory parameter is that, since calls to jest.mock() are hoisted to the top of the file, it's not possible to first define a variable and then use it in the factory. An exception is made for variables that start with the word 'mock'. It's up to you to guarantee that they will be initialized on time!
What that means is you need to move around the lines of code to make them look like this:
// 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', () => ({
// ...
}));
The second issue is that you are mocking File2
as if it was exporting method1
and method2
, you are not mocking method1
and method2
of the File2
class! Take a look at 4 ways of mocking an ES6 class in jest docs.
Upvotes: 15