Documentation Index Fetch the complete documentation index at: https://mintlify.com/rjdellecese/confect/llms.txt
Use this file to discover all available pages before exploring further.
Confect provides a powerful testing package (@confect/test) built on top of convex-test that makes it easy to test queries, mutations, and actions in your application.
Installation
The testing package is included in the Confect monorepo:
npm install @confect/test convex-test
Setting Up Tests
The @confect/test package provides a TestConfect service that allows you to run your functions in a test environment.
Basic Test Setup
import { TestConfect } from "@confect/test" ;
import { Effect } from "effect" ;
import { describe , test } from "vitest" ;
import { databaseSchema } from "../confect/schema" ;
import { refs } from "../confect/_generated/refs" ;
const TestLayer = TestConfect . layer (
databaseSchema ,
import . meta . glob ( "../convex/**/*.js" )
)();
describe ( "My Tests" , () => {
test ( "example test" , async () => {
await Effect . gen ( function* () {
const t = yield * TestConfect ();
// Your test code here
}). pipe (
Effect . provide ( TestLayer ),
Effect . runPromise
);
});
});
Testing Queries
Type-Safe Queries Test queries with full type safety and schema validation
Fast Execution Tests run against an in-memory database for speed
Query Testing Example
import { TestConfect } from "@confect/test" ;
import { Effect } from "effect" ;
import { refs } from "../confect/_generated/refs" ;
test ( "should fetch user by ID" , async () => {
await Effect . gen ( function* () {
const t = yield * TestConfect ();
// Insert test data
yield * t . run ( function* () {
const db = yield * DatabaseWriter ();
yield * db . table ( "users" ). insert ({
name: "Alice" ,
email: "alice@example.com"
});
});
// Query the data
const users = yield * t . query (
refs . public . users . list ,
{}
);
expect ( users ). toHaveLength ( 1 );
expect ( users [ 0 ]. name ). toBe ( "Alice" );
}). pipe (
Effect . provide ( TestLayer ),
Effect . runPromise
);
});
Testing Mutations
Mutations can be tested using the mutation method on the TestConfect service.
Mutation Testing Example
test ( "should create a new user" , async () => {
await Effect . gen ( function* () {
const t = yield * TestConfect ();
// Call the mutation
const userId = yield * t . mutation (
refs . public . users . create ,
{
name: "Bob" ,
email: "bob@example.com"
}
);
expect ( userId ). toBeDefined ();
// Verify the mutation worked
const users = yield * t . query (
refs . public . users . getById ,
{ id: userId }
);
expect ( users ?. name ). toBe ( "Bob" );
}). pipe (
Effect . provide ( TestLayer ),
Effect . runPromise
);
});
Testing Actions
Actions can be tested similarly to mutations and queries.
Action Testing Example
test ( "should send email notification" , async () => {
await Effect . gen ( function* () {
const t = yield * TestConfect ();
const result = yield * t . action (
refs . public . notifications . sendEmail ,
{
to: "user@example.com" ,
subject: "Test" ,
body: "Test message"
}
);
expect ( result . success ). toBe ( true );
}). pipe (
Effect . provide ( TestLayer ),
Effect . runPromise
);
});
Running Custom Logic with run
The run method allows you to execute custom logic with full access to mutation services.
The run method provides access to DatabaseWriter, DatabaseReader, Scheduler, Storage, and Auth services.
test ( "should create multiple related records" , async () => {
await Effect . gen ( function* () {
const t = yield * TestConfect ();
yield * t . run ( function* () {
const db = yield * DatabaseWriter ();
const auth = yield * Auth ();
// Create a user
const userId = yield * db . table ( "users" ). insert ({
name: "Charlie" ,
email: "charlie@example.com"
});
// Create posts for the user
yield * db . table ( "posts" ). insert ({
userId ,
title: "First Post" ,
content: "Hello world!"
});
});
}). pipe (
Effect . provide ( TestLayer ),
Effect . runPromise
);
});
Testing with Authentication
You can test functions that require authentication using the withIdentity method.
test ( "should access user-specific data" , async () => {
await Effect . gen ( function* () {
const t = yield * TestConfect ();
// Test as an authenticated user
const tWithAuth = t . withIdentity ({
subject: "user123" ,
name: "Test User" ,
email: "test@example.com"
});
const profile = yield * tWithAuth . query (
refs . public . users . getMyProfile ,
{}
);
expect ( profile ). toBeDefined ();
}). pipe (
Effect . provide ( TestLayer ),
Effect . runPromise
);
});
Testing Scheduled Functions
Confect supports testing scheduled functions and cron jobs.
finishInProgressScheduledFunctions Complete all currently scheduled functions
finishAllScheduledFunctions Complete all scheduled functions with timer advancement
test ( "should process scheduled tasks" , async () => {
await Effect . gen ( function* () {
const t = yield * TestConfect ();
// Schedule a function
yield * t . mutation (
refs . public . tasks . scheduleTask ,
{ taskName: "cleanup" , delayMs: 5000 }
);
// Finish in-progress scheduled functions
yield * t . finishInProgressScheduledFunctions ();
// Verify the task was processed
const tasks = yield * t . query (
refs . public . tasks . list ,
{ status: "completed" }
);
expect ( tasks ). toHaveLength ( 1 );
}). pipe (
Effect . provide ( TestLayer ),
Effect . runPromise
);
});
Testing HTTP Routes
You can test HTTP endpoints using the fetch method.
test ( "should handle HTTP requests" , async () => {
await Effect . gen ( function* () {
const t = yield * TestConfect ();
const response = yield * t . fetch ( "/api/health" );
expect ( response . status ). toBe ( 200 );
const data = yield * Effect . promise (() => response . json ());
expect ( data . status ). toBe ( "ok" );
}). pipe (
Effect . provide ( TestLayer ),
Effect . runPromise
);
});
Best Practices
Isolation Each test gets a fresh database instance for complete isolation
Type Safety Leverage TypeScript types for compile-time safety
Real Schema Tests use your actual schema for realistic validation
Fast Feedback In-memory execution provides instant test results
Test Organization
describe ( "Users API" , () => {
describe ( "Queries" , () => {
test ( "list users" , async () => {
// Test implementation
});
test ( "get user by ID" , async () => {
// Test implementation
});
});
describe ( "Mutations" , () => {
test ( "create user" , async () => {
// Test implementation
});
test ( "update user" , async () => {
// Test implementation
});
});
});
Next Steps
API Reference Explore the complete Confect API
Server Guide Learn about server-side APIs