TripleSpeeder
TripleSpeeder16mo ago

Does anyone here have success/working

Does anyone here have success/working example how to mock convex hooks? I tried to follow the injection test example with fakeConvexClient from convex-helpers repo. But no matter how i try to set it up I get the error TypeError: Cannot convert object to primitive value at Object.localQueryResult. This also happens if you run tests in the convex-helpers repo, so probably fakeConvexClient class is outdated...
2 Replies
TripleSpeeder
TripleSpeederOP16mo ago
I quickly hacked something together for storybook, to be used with the storybook-addon-module-mock addon:
import { createMock } from "storybook-addon-module-mock";
import * as convexReact from "convex/react";
import { getFunctionName } from "convex/server";
import { manufacturer, partReplacedBrake } from "@/convexMocks/testDocs";

export const useConvexMock = () => {
const useQueryMock = createMock(convexReact, "useQuery");
useQueryMock.mockImplementation((query, ...args) => {
if (args[0] === "skip") {
return undefined;
}
const queryName = getFunctionName(query);
switch (queryName) {
case "manufacturer:getManufacturer":
return manufacturer;
case "part:getPart":
return partReplacedBrake;
default:
throw new Error(
`Unexpected query call ${queryName}! Please add a mock :)`,
);
}
});
return [useQueryMock];
};
import { createMock } from "storybook-addon-module-mock";
import * as convexReact from "convex/react";
import { getFunctionName } from "convex/server";
import { manufacturer, partReplacedBrake } from "@/convexMocks/testDocs";

export const useConvexMock = () => {
const useQueryMock = createMock(convexReact, "useQuery");
useQueryMock.mockImplementation((query, ...args) => {
if (args[0] === "skip") {
return undefined;
}
const queryName = getFunctionName(query);
switch (queryName) {
case "manufacturer:getManufacturer":
return manufacturer;
case "part:getPart":
return partReplacedBrake;
default:
throw new Error(
`Unexpected query call ${queryName}! Please add a mock :)`,
);
}
});
return [useQueryMock];
};
It works for now but is not very flexible 🤷‍♂️
sshader
sshader16mo ago
Yeah looks like fakeConvexClient in convex-helpers is out of date. Thanks for reporting and I'll look into updating that. Here's an attempt at patching it:
- watchQuery(name, args) {
+ watchQuery(query, args) {
return {
localQueryResult: () => {
- const query = this.queries && this.queries[name];
- if (query) {
- return query(args);
+ const name = getFunctionName(query);
+ const queryImpl = this.queries && this.queries[name];
+ if (queryImpl) {
+ return queryImpl(args);
}
throw new Error(
`Unexpected query: ${name}. Try providing a function for this query in the mock client constructor.`
@@ -43,23 +44,19 @@ export class ConvexReactClientFake {
};
}

- mutation(name) {
- const mutation = this.mutations && this.mutations[name];
- if (mutation) {
- const mut = (args) => mutation(args);
-
- const withOptimisticUpdate = mutation.withOptimisticUpdate
- ? mutation.withOptimisticUpdate
- : () => mut;
- mut.withOptimisticUpdate = withOptimisticUpdate;
- return mut;
+ mutation(mutationRef, args) {
+ const name = getFunctionName(mutationRef);
+ const mutationImpl = this.mutations && this.mutations[name];
+ if (mutationImpl) {
+ return mutationImpl(args);
- watchQuery(name, args) {
+ watchQuery(query, args) {
return {
localQueryResult: () => {
- const query = this.queries && this.queries[name];
- if (query) {
- return query(args);
+ const name = getFunctionName(query);
+ const queryImpl = this.queries && this.queries[name];
+ if (queryImpl) {
+ return queryImpl(args);
}
throw new Error(
`Unexpected query: ${name}. Try providing a function for this query in the mock client constructor.`
@@ -43,23 +44,19 @@ export class ConvexReactClientFake {
};
}

- mutation(name) {
- const mutation = this.mutations && this.mutations[name];
- if (mutation) {
- const mut = (args) => mutation(args);
-
- const withOptimisticUpdate = mutation.withOptimisticUpdate
- ? mutation.withOptimisticUpdate
- : () => mut;
- mut.withOptimisticUpdate = withOptimisticUpdate;
- return mut;
+ mutation(mutationRef, args) {
+ const name = getFunctionName(mutationRef);
+ const mutationImpl = this.mutations && this.mutations[name];
+ if (mutationImpl) {
+ return mutationImpl(args);

Did you find this page helpful?