INTEGRITY Документация

Работа с Workers

Используйте тестовый стенд, чтобы отправлять запросы через настроенные маршруты или напрямую обращаться к конкретному Worker. Также можно отправлять события, например запланированные события.

Тестирование маршрутизации между Workers

Если тестовый набор запускает несколько Workers, добавьте каждый Worker в workers массив. Первый Worker является основным Worker. server.fetch() отправляет относительные URL-адреса на основной Worker, а абсолютные URL-адреса сопоставляет с настроенными маршрутами. Если ни один маршрут не совпадает, запрос возвращается к основному Worker:

const server = createTestHarness({
	workers: [
		/** Includes `"routes": ["example.com/*"]` */
		{ configPath: "./workers/web/wrangler.jsonc" },
		/** Includes `"routes": ["api.example.com/v1/*"]` */
		{ configPath: "./workers/api/wrangler.jsonc" },
	],
});

const primaryResponse = await server.fetch("/");
const apiResponse = await server.fetch("http://api.example.com/v1/users/123");
const webResponse = await server.fetch("http://example.com/users/123");
const server = createTestHarness({
	workers: [
		/** Includes `"routes": ["example.com/*"]` */
		{ configPath: "./workers/web/wrangler.jsonc" },
		/** Includes `"routes": ["api.example.com/v1/*"]` */
		{ configPath: "./workers/api/wrangler.jsonc" },
	],
});

const primaryResponse = await server.fetch("/");
const apiResponse = await server.fetch("http://api.example.com/v1/users/123");
const webResponse = await server.fetch("http://example.com/users/123");

Работа с определённым Worker

Диспетчеризация маршрутов проверяет границу приложения, но некоторые тесты могут быть нацелены на конкретный Worker или на вызов других обработчиков событий. Используйте server.getWorker(name) чтобы обойти сопоставление маршрутов и получить handle для этого Worker.

Затем этот Worker handle можно использовать для отправки запросов напрямую или для диспетчеризации других событий, например scheduled():

const apiWorker = server.getWorker("api-worker");
const response = await apiWorker.fetch("http://api.example.com/v1/users/123");

await apiWorker.scheduled({
	cron: "0 0 * * *",
	scheduledTime: new Date(),
});
const apiWorker = server.getWorker("api-worker");
const response = await apiWorker.fetch("http://api.example.com/v1/users/123");

await apiWorker.scheduled({
	cron: "0 0 * * *",
	scheduledTime: new Date(),
});

Проверка поведения по логам

Тестовое окружение перехватывает логи из среды выполнения Workers. Чтобы убедиться, что Worker записал определённое сообщение в лог, используйте server.getLogs() чтобы получить записи журнала.

Захваченные логи сбрасываются при вызове server.reset(). Также можно вызвать server.clearLogs() чтобы выделить логи до и после определенного действия:

test("logs scheduled job results", async ({ expect }) => {
	const apiWorker = server.getWorker("api-worker");

	await apiWorker.scheduled({
		cron: "0 0 * * *",
		scheduledTime: new Date("2026-05-29T00:00:00.000Z"),
	});

	expect(server.getLogs()).toEqual([
		expect.objectContaining({
			level: "info",
			message: "Generated daily report for 2026-05-29",
		}),
	]);

	server.clearLogs();

	await apiWorker.scheduled({
		cron: "0 0 * * *",
		scheduledTime: new Date("2026-05-30T00:00:00.000Z"),
	});

	expect(server.getLogs()).toEqual([
		expect.objectContaining({
			level: "info",
			message: "Generated daily report for 2026-05-30",
		}),
	]);
});
test("logs scheduled job results", async ({ expect }) => {
	const apiWorker = server.getWorker("api-worker");

	await apiWorker.scheduled({
		cron: "0 0 * * *",
		scheduledTime: new Date("2026-05-29T00:00:00.000Z"),
	});

	expect(server.getLogs()).toEqual([
		expect.objectContaining({
			level: "info",
			message: "Generated daily report for 2026-05-29",
		}),
	]);

	server.clearLogs();

	await apiWorker.scheduled({
		cron: "0 0 * * *",
		scheduledTime: new Date("2026-05-30T00:00:00.000Z"),
	});

	expect(server.getLogs()).toEqual([
		expect.objectContaining({
			level: "info",
			message: "Generated daily report for 2026-05-30",
		}),
	]);
});

Просмотр и управление выполнением Workflow

Если ваш Worker запускает Workflow, вы можете использовать worker.introspectWorkflow(bindingName) чтобы управлять новыми экземплярами и просматривать их состояние.

const worker = server.getWorker("api-worker");
await using workflow = await worker.introspectWorkflow("MY_WORKFLOW");

await workflow.modifyAll(async (modifier) => {
	await modifier.disableSleeps([{ name: "wait-for-approval" }]);
});

await worker.fetch("/start-workflow");

const [instance] = await workflow.get();
await instance.waitForStatus("complete");
expect(await instance.getOutput()).toEqual({ approved: true });
const worker = server.getWorker<ApiEnv>("api-worker");
await using workflow = await worker.introspectWorkflow("MY_WORKFLOW");

await workflow.modifyAll(async (modifier) => {
	await modifier.disableSleeps([{ name: "wait-for-approval" }]);
});

await worker.fetch("/start-workflow");

const [instance] = await workflow.get();
await instance.waitForStatus("complete");
expect(await instance.getOutput()).toEqual({ approved: true });

Если тесту уже известен ID экземпляра, вы также можете исследовать этот экземпляр напрямую с помощью worker.introspectWorkflowInstance(bindingName, instanceId).

const instance = await worker.introspectWorkflowInstance(
	"MY_WORKFLOW",
	"instance-id",
);

await instance.modify(async (modifier) => {
	await modifier.mockStepResult({ name: "load-user" }, { id: "123" });
});

await instance.waitForStatus("complete");
const instance = await worker.introspectWorkflowInstance(
	"MY_WORKFLOW",
	"instance-id",
);

await instance.modify(async (modifier) => {
	await modifier.mockStepResult({ name: "load-user" }, { id: "123" });
});

await instance.waitForStatus("complete");