Skip to content

Commit af167c6

Browse files
committed
Remove as unknown as DatabaseManager
Unfortunately `Object.defineProperty` doesn't work on proxies, so I've added an options object to `mockedObject` which allows passing in methods that will return a value for a specific property.
1 parent 551ed95 commit af167c6

File tree

2 files changed

+35
-13
lines changed

2 files changed

+35
-13
lines changed

extensions/ql-vscode/test/vscode-tests/no-workspace/test-adapter.test.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -59,18 +59,20 @@ describe("test-adapter", () => {
5959
setCurrentDatabaseItemSpy.mockResolvedValue(undefined);
6060
resolveQlpacksSpy.mockResolvedValue({});
6161
resolveTestsSpy.mockResolvedValue([]);
62-
fakeDatabaseManager = {
63-
openDatabase: openDatabaseSpy,
64-
removeDatabaseItem: removeDatabaseItemSpy,
65-
renameDatabaseItem: renameDatabaseItemSpy,
66-
setCurrentDatabaseItem: setCurrentDatabaseItemSpy,
67-
} as unknown as DatabaseManager;
68-
Object.defineProperty(fakeDatabaseManager, "currentDatabaseItem", {
69-
get: () => currentDatabaseItem,
70-
});
71-
Object.defineProperty(fakeDatabaseManager, "databaseItems", {
72-
get: () => databaseItems,
73-
});
62+
fakeDatabaseManager = mockedObject<DatabaseManager>(
63+
{
64+
openDatabase: openDatabaseSpy,
65+
removeDatabaseItem: removeDatabaseItemSpy,
66+
renameDatabaseItem: renameDatabaseItemSpy,
67+
setCurrentDatabaseItem: setCurrentDatabaseItemSpy,
68+
},
69+
{
70+
dynamicProperties: {
71+
currentDatabaseItem: () => currentDatabaseItem,
72+
databaseItems: () => databaseItems,
73+
},
74+
},
75+
);
7476

7577
jest.spyOn(preTestDatabaseItem, "isAffectedByTest").mockResolvedValue(true);
7678

extensions/ql-vscode/test/vscode-tests/utils/mocking.helpers.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,32 @@ export type DeepPartial<T> = T extends object
44
}
55
: T;
66

7-
export function mockedObject<T extends object>(props: DeepPartial<T>): T {
7+
export type DynamicProperties<T extends object> = {
8+
[P in keyof T]?: () => T[P];
9+
};
10+
11+
type MockedObjectOptions<T extends object> = {
12+
/**
13+
* Properties for which the given method should be called when accessed.
14+
* The method should return the value to be returned when the property is accessed.
15+
* Methods which are explicitly defined in `methods` will take precedence over
16+
* dynamic properties.
17+
*/
18+
dynamicProperties?: DynamicProperties<T>;
19+
};
20+
21+
export function mockedObject<T extends object>(
22+
props: DeepPartial<T>,
23+
{ dynamicProperties }: MockedObjectOptions<T> = {},
24+
): T {
825
return new Proxy<T>({} as unknown as T, {
926
get: (_target, prop) => {
1027
if (prop in props) {
1128
return (props as any)[prop];
1229
}
30+
if (dynamicProperties && prop in dynamicProperties) {
31+
return (dynamicProperties as any)[prop]();
32+
}
1333
throw new Error(`Method ${String(prop)} not mocked`);
1434
},
1535
});

0 commit comments

Comments
 (0)