Skip to content

Commit 45cda6c

Browse files
feat: instance accessibility for tests (#176)
This patch uses the instance constructor context to be able to save mockInstances locally to the inherited class tree, and dynamically keeps a list of these contexts to clear them automatically afterEach jest test. See mvcobject.test.ts for an example.
1 parent 3af17ea commit 45cda6c

File tree

4 files changed

+66
-3
lines changed

4 files changed

+66
-3
lines changed

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
[![](https://github.com/jpoehnelt/in-solidarity-bot/raw/main/static//badge-flat.png)](https://github.com/apps/in-solidarity)
1010
[![Discord](https://img.shields.io/discord/676948200904589322?color=6A7EC2&logo=discord&logoColor=ffffff)](https://discord.gg/jRteCzP)
1111

12-
1312
## Description
1413

1514
Jest mocks for Google Maps in TypeScript.
@@ -23,12 +22,16 @@ Available via NPM as the package `@googlemaps/jest-mocks`
2322
## Example
2423

2524
```typescript
26-
import { initialize } from "@googlemaps/jest-mocks";
25+
import { initialize, Map } from "@googlemaps/jest-mocks";
2726

2827
beforeEach(() => {
2928
initialize();
3029
});
3130

31+
// access the object instances if the object isn't easily accessible
32+
test("my test", () => {
33+
expect(Map.mockInstances[0].fitBounds).toHaveBeenCalled();
34+
});
3235
```
3336

3437
## Support

src/maps/event/mvcobject.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { initialize } from "../../index";
2+
import { Map_ } from "../maps/map";
3+
import { MVCObject } from "./mvcobject";
4+
5+
test("instances are stored", () => {
6+
const mvcObject = new MVCObject();
7+
expect(MVCObject.mockInstances).toStrictEqual([mvcObject]);
8+
expect(MVCObject.mockInstances[0].addListener).toBeTruthy();
9+
});
10+
11+
test("setup child class", () => {
12+
initialize();
13+
new google.maps.Map(null);
14+
expect(Map_.mockInstances).toBeTruthy();
15+
});
16+
17+
test("auto cleanup after each test from above", () => {
18+
expect(MVCObject.mockInstances).toBeUndefined();
19+
expect(Map_.mockInstances).toBeUndefined();
20+
expect(MVCObject._mockClasses).toBeUndefined();
21+
});

src/maps/event/mvcobject.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,24 @@
1717
/* eslint-disable @typescript-eslint/no-explicit-any */
1818

1919
export class MVCObject implements google.maps.MVCObject {
20+
public static _mockClasses: typeof MVCObject[] = [];
21+
public static mockInstances: MVCObject[] = [];
22+
23+
public constructor() {
24+
const ctor = this.constructor as typeof MVCObject;
25+
26+
if (ctor.mockInstances === undefined) {
27+
ctor.mockInstances = [];
28+
}
29+
30+
if (MVCObject._mockClasses === undefined) {
31+
MVCObject._mockClasses = [];
32+
}
33+
34+
ctor.mockInstances.push(this);
35+
MVCObject._mockClasses.push(ctor);
36+
}
37+
2038
public addListener = jest
2139
.fn()
2240
.mockImplementation(
@@ -42,3 +60,16 @@ export class MVCObject implements google.maps.MVCObject {
4260
public unbind = jest.fn().mockImplementation((key: string): void => null);
4361
public unbindAll = jest.fn().mockImplementation(() => null);
4462
}
63+
64+
// if running a test that supports afterEach, then we will cleanup the instances
65+
// automatically at the end of each test.
66+
if (typeof afterEach === "function") {
67+
afterEach(() => {
68+
if (MVCObject._mockClasses) {
69+
for (const ctor of MVCObject._mockClasses) {
70+
ctor.mockInstances = undefined;
71+
}
72+
}
73+
MVCObject._mockClasses = undefined;
74+
});
75+
}

src/maps/maps/map.test.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,22 @@
1616

1717
import { initialize } from "../../index";
1818
import { ControlPosition } from "../controls/controlposition";
19+
import { Map_ } from "./map";
1920

2021
test("can initialize", () => {
2122
initialize();
2223
expect(new google.maps.Map(null)).toBeTruthy();
2324
});
2425

25-
test("controls initalized", () => {
26+
test("controls initialized", () => {
2627
initialize();
2728
const map = new google.maps.Map(null);
2829
expect(map.controls[ControlPosition.BOTTOM_CENTER]).toBeTruthy();
2930
});
31+
32+
test("mockInstances available", () => {
33+
initialize();
34+
new google.maps.MVCObject();
35+
const map = new google.maps.Map(null);
36+
expect(Map_.mockInstances).toMatchObject([map]);
37+
});

0 commit comments

Comments
 (0)