Integration / unit / e2e testing patterns #2751
Replies: 1 comment
-
|
I would also really like to see some recommended patterns within the official documentation for writing unit or integration tests. Especially when using middleware/locals. For now, I've create a vitest mock of the I made this so that I can call import { vi } from "vitest";
interface TaskConfig {
id: string;
run: (payload: any) => Promise<any>;
}
class TriggerSdk {
_tasks = new Map<string, TaskConfig>();
_locals = new Map<string, any>();
_middleware = new Map<
string,
({ next }: { next: () => Promise<any> }) => Promise<any>
>();
task = (config: TaskConfig) => {
console.log("task", config);
this._tasks.set(config.id, config);
return {
trigger: this._trigger(config),
batchTrigger: this._batchTrigger(config),
};
};
schemaTask = (config: TaskConfig) => {
console.log("schemaTask", config);
this._tasks.set(config.id, config);
return {
trigger: this._trigger(config),
batchTrigger: this._batchTrigger(config),
};
};
schedules = {
task: (config: TaskConfig) => {
console.log("schedule task", config);
this._tasks.set(config.id, config);
return {
trigger: this._trigger(config),
batchTrigger: this._batchTrigger(config),
};
},
};
_trigger = (config: TaskConfig) => {
return vi.fn(async (payload: any) => {
return this._execute(config.id, payload);
});
};
_execute = async (id: string, payload: any) => {
const task = this._tasks.get(id);
if (!task) {
throw new Error(`Task ${id} not found`);
}
const middlewares = Array.from(this._middleware.entries());
let chain: () => Promise<any> = () => {
console.log("running task", id);
return task.run(payload);
};
for (let i = middlewares.length - 1; i >= 0; i--) {
const [id, middleware] = middlewares[i]!;
const next = chain;
chain = () => {
console.log("running middleware", id);
return middleware({ next });
};
}
return chain();
};
_batchTrigger = (config: TaskConfig) => {
return vi.fn(async (items: Array<{ payload: any }>) => {
const results = await Promise.all(
items.map((item) => this._trigger(config)(item.payload)),
);
return { runs: results };
});
};
tasks = {
middleware: (id: string, fn: () => Promise<any>) => {
this._middleware.set(id, fn);
},
onWait: (id: string, fn: () => Promise<any>) => {
console.log("onWait", id, fn);
},
onResume: (id: string, fn: () => Promise<any>) => {
console.log("onResume", id, fn);
},
};
locals = {
create: (id: string) => {
this._locals.set(id, {});
return id;
},
getOrThrow: (id: string) => {
const local = this._locals.get(id);
if (!local) {
throw new Error(`Local ${id} not found`);
}
return local;
},
set: (id: string, value: any) => {
this._locals.set(id, value);
return value;
},
};
logger = {
error: vi.fn(),
log: vi.fn(),
trace: vi.fn(),
};
tags = {
add: vi.fn(),
};
}
export const { locals, task, tasks, schedules, logger, schemaTask, tags } =
new TriggerSdk();In my vitest, I'm just aliasing the official package with this file: export default defineConfig({
test: {
environment: "node",
setupFiles: ["./test/setup.ts"],
},
resolve: {
alias: {
"~": path.resolve(__dirname, "./src"),
"@trigger.dev/sdk": path.resolve(__dirname, "./test/trigger.dev/sdk.ts"),
},
},
});Note, if your task calls another task within itself, it will trigger in the same test run. I'm using |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Since trigger.dev doesn't provide any mocking utils for the tasks, anyone has some good patterns for testing them? Maybe someone create their own mocked version of task or schemaTask?
Beta Was this translation helpful? Give feedback.
All reactions