or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

ace-commands.mdapplication.mdauth-hash.mdcommands.mdconfig-env.mdevents.mdhelpers.mdhttp-server.mdindex.mdlogging.mdtest-utils.md
tile.json

test-utils.mddocs/

Test Utilities

Testing helpers and utilities for building robust test suites in AdonisJS applications. Provides comprehensive testing support for HTTP endpoints, database operations, and application lifecycle management.

Capabilities

Test Utils

Main test utilities class providing access to various testing helpers.

/**
 * Test utilities for AdonisJS application testing
 */
class TestUtils {
  /**
   * Create test utils instance
   * @param app - Application instance
   */
  constructor(app: ApplicationService);

  /**
   * Clean up test environment
   * Resets application state, clears caches, etc.
   */
  cleanup(): Promise<void>;

  /**
   * Get database test utilities
   * @returns Database testing helpers
   */
  db(): DatabaseTestUtils;

  /**
   * Get HTTP server test utilities
   * @returns HTTP testing helpers
   */
  httpServer(): HttpTestUtils;

  /**
   * Get file system test utilities
   * @returns File system testing helpers
   */
  fs(): FileSystemTestUtils;

  /**
   * Create test application instance
   * @param options - Application options for testing
   * @returns Test application instance
   */
  createApp(options?: TestAppOptions): Promise<ApplicationService>;

  /**
   * Destroy test application
   * @param app - Application to destroy
   */
  destroyApp(app: ApplicationService): Promise<void>;
}

Usage Examples:

import { TestUtils } from "@adonisjs/core/test_utils";
import { test } from "@japa/runner";

test.group('User API', (group) => {
  let testUtils: TestUtils;

  group.setup(async () => {
    const app = await createApp();
    testUtils = new TestUtils(app);
  });

  group.teardown(async () => {
    await testUtils.cleanup();
  });

  test('should create user', async ({ assert }) => {
    const response = await testUtils.httpServer()
      .post('/api/users')
      .json({
        name: 'John Doe',
        email: 'john@example.com'
      });

    assert.equal(response.status(), 201);
    assert.equal(response.body().name, 'John Doe');
  });
});

HTTP Test Utils

HTTP testing utilities for testing API endpoints and web routes.

/**
 * HTTP testing utilities for API and web testing
 */
class HttpTestUtils {
  /**
   * Make GET request
   * @param url - Request URL
   * @returns HTTP test request
   */
  get(url: string): HttpTestRequest;

  /**
   * Make POST request
   * @param url - Request URL
   * @returns HTTP test request
   */
  post(url: string): HttpTestRequest;

  /**
   * Make PUT request
   * @param url - Request URL
   * @returns HTTP test request
   */
  put(url: string): HttpTestRequest;

  /**
   * Make PATCH request
   * @param url - Request URL
   * @returns HTTP test request
   */
  patch(url: string): HttpTestRequest;

  /**
   * Make DELETE request
   * @param url - Request URL
   * @returns HTTP test request
   */
  delete(url: string): HttpTestRequest;

  /**
   * Start test server
   * @param callback - Optional callback when server is ready
   */
  start(callback?: () => void): Promise<void>;

  /**
   * Stop test server
   */
  stop(): Promise<void>;

  /**
   * Get server URL
   * @returns Base server URL for testing
   */
  getUrl(): string;
}

/**
 * HTTP test request builder
 */
class HttpTestRequest {
  /**
   * Set request headers
   * @param headers - Headers object or key-value pairs
   * @returns This request for chaining
   */
  headers(headers: Record<string, string>): this;

  /**
   * Set single header
   * @param key - Header name
   * @param value - Header value
   * @returns This request for chaining
   */
  header(key: string, value: string): this;

  /**
   * Set JSON body
   * @param data - JSON data to send
   * @returns This request for chaining
   */
  json(data: any): this;

  /**
   * Set form data body
   * @param data - Form data to send
   * @returns This request for chaining
   */
  form(data: Record<string, any>): this;

  /**
   * Upload files
   * @param data - Files and form fields
   * @returns This request for chaining
   */
  files(data: Record<string, any>): this;

  /**
   * Set query parameters
   * @param params - Query parameters
   * @returns This request for chaining
   */
  qs(params: Record<string, any>): this;

  /**
   * Set authentication header
   * @param token - Auth token
   * @param type - Auth type (default: 'Bearer')
   * @returns This request for chaining
   */
  auth(token: string, type?: string): this;

  /**
   * Execute request and get response
   * @returns HTTP test response
   */
  expect(): Promise<HttpTestResponse>;

  /**
   * Execute request (alias for expect)
   * @returns HTTP test response
   */
  send(): Promise<HttpTestResponse>;
}

/**
 * HTTP test response
 */
class HttpTestResponse {
  /**
   * Get response status code
   * @returns HTTP status code
   */
  status(): number;

  /**
   * Get response body
   * @returns Response body (parsed if JSON)
   */
  body(): any;

  /**
   * Get response headers
   * @returns Response headers object
   */
  headers(): Record<string, string>;

  /**
   * Get specific header
   * @param name - Header name
   * @returns Header value
   */
  header(name: string): string | undefined;

  /**
   * Get raw response text
   * @returns Raw response body as string
   */
  text(): string;

  /**
   * Assert response status
   * @param expectedStatus - Expected status code
   */
  assertStatus(expectedStatus: number): void;

  /**
   * Assert response body contains
   * @param expected - Expected content
   */
  assertBodyContains(expected: any): void;

  /**
   * Assert response header
   * @param name - Header name
   * @param value - Expected header value
   */
  assertHeader(name: string, value: string): void;
}

Usage Examples:

import { test } from "@japa/runner";

test('User registration endpoint', async ({ assert }) => {
  const response = await testUtils.httpServer()
    .post('/auth/register')
    .json({
      name: 'Jane Smith',
      email: 'jane@example.com',
      password: 'secret123'
    })
    .expect();

  assert.equal(response.status(), 201);
  assert.property(response.body(), 'user');
  assert.property(response.body(), 'token');
});

test('Protected endpoint with auth', async ({ assert }) => {
  const token = await getAuthToken();
  
  const response = await testUtils.httpServer()
    .get('/api/profile')
    .auth(token)
    .expect();

  assert.equal(response.status(), 200);
  response.assertBodyContains({
    name: 'John Doe',
    email: 'john@example.com'
  });
});

Database Test Utils

Database testing utilities for managing test data and database state.

/**
 * Database testing utilities
 */
class DatabaseTestUtils {
  /**
   * Truncate all tables
   * Clears all data from database tables
   */
  truncate(): Promise<void>;

  /**
   * Truncate specific tables
   * @param tables - Array of table names to truncate
   */
  truncateTables(tables: string[]): Promise<void>;

  /**
   * Seed database with test data
   * @param seeder - Seeder class or function
   */
  seed(seeder?: any): Promise<void>;

  /**
   * Run database migrations
   */
  migrate(): Promise<void>;

  /**
   * Rollback database migrations
   */
  rollback(): Promise<void>;

  /**
   * Create database transaction for test isolation
   * @returns Database transaction
   */
  transaction(): Promise<DatabaseTransaction>;

  /**
   * Create test factory for model
   * @param model - Model class
   * @returns Factory instance
   */
  factory<T>(model: T): Factory<T>;

  /**
   * Insert test data directly
   * @param table - Table name
   * @param data - Data to insert
   */
  insertData(table: string, data: any[]): Promise<void>;

  /**
   * Get test database connection
   * @returns Database connection for testing
   */
  connection(): DatabaseConnection;
}

/**
 * Model factory for generating test data
 */
class Factory<T> {
  /**
   * Create single model instance
   * @param attributes - Override attributes
   * @returns Created model instance
   */
  create(attributes?: Partial<T>): Promise<T>;

  /**
   * Create multiple model instances
   * @param count - Number of instances to create
   * @param attributes - Override attributes
   * @returns Array of created instances
   */
  createMany(count: number, attributes?: Partial<T>): Promise<T[]>;

  /**
   * Make model instance without persisting
   * @param attributes - Override attributes
   * @returns Model instance (not saved)
   */
  make(attributes?: Partial<T>): T;

  /**
   * Make multiple model instances without persisting
   * @param count - Number of instances to make
   * @param attributes - Override attributes
   * @returns Array of model instances
   */
  makeMany(count: number, attributes?: Partial<T>): T[];

  /**
   * Define custom state
   * @param name - State name
   * @param callback - State modifier function
   * @returns This factory for chaining
   */
  state(name: string, callback: (attributes: Partial<T>) => Partial<T>): this;

  /**
   * Apply state to factory
   * @param stateName - Name of state to apply
   * @returns This factory for chaining
   */
  apply(stateName: string): this;
}

Usage Examples:

test.group('User model', (group) => {
  group.setup(async () => {
    await testUtils.db().migrate();
  });

  group.teardown(async () => {
    await testUtils.db().rollback();
  });

  test('should create user', async ({ assert }) => {
    const user = await testUtils.db()
      .factory(User)
      .create({
        email: 'test@example.com'
      });

    assert.equal(user.email, 'test@example.com');
    assert.exists(user.id);
  });

  test('should create multiple users', async ({ assert }) => {
    const users = await testUtils.db()
      .factory(User)
      .createMany(5);

    assert.lengthOf(users, 5);
  });
});

File System Test Utils

File system testing utilities for testing file operations.

/**
 * File system testing utilities
 */
class FileSystemTestUtils {
  /**
   * Create temporary directory for testing
   * @param prefix - Directory name prefix
   * @returns Temporary directory path
   */
  createTempDir(prefix?: string): Promise<string>;

  /**
   * Create temporary file for testing
   * @param content - File content
   * @param extension - File extension
   * @returns Temporary file path
   */
  createTempFile(content: string, extension?: string): Promise<string>;

  /**
   * Clean up temporary files and directories
   */
  cleanup(): Promise<void>;

  /**
   * Assert file exists
   * @param filePath - Path to file
   */
  assertExists(filePath: string): void;

  /**
   * Assert file does not exist
   * @param filePath - Path to file
   */
  assertNotExists(filePath: string): void;

  /**
   * Assert file contains content
   * @param filePath - Path to file
   * @param expectedContent - Expected content
   */
  assertFileContains(filePath: string, expectedContent: string): void;

  /**
   * Create mock file upload
   * @param options - Upload file options
   * @returns Mock file upload object
   */
  createFileUpload(options: FileUploadOptions): MockFileUpload;
}

/**
 * Mock file upload for testing
 */
interface MockFileUpload {
  /** Original filename */
  clientName: string;
  /** File size */
  size: number;
  /** MIME type */
  type: string;
  /** File content */
  content: Buffer;
  /** Move to destination (mock) */
  move(destination: string): Promise<void>;
  /** Check if valid */
  isValid: boolean;
  /** Mock errors */
  errors: Error[];
}

Usage Examples:

test('File upload processing', async ({ assert }) => {
  const mockFile = testUtils.fs().createFileUpload({
    filename: 'test.jpg',
    content: Buffer.from('fake image data'),
    mimeType: 'image/jpeg'
  });

  const response = await testUtils.httpServer()
    .post('/upload')
    .files({ avatar: mockFile })
    .expect();

  assert.equal(response.status(), 200);
  testUtils.fs().assertExists('./uploads/test.jpg');
});

Types

interface TestAppOptions {
  environment?: string;
  configOverrides?: Record<string, any>;
}

interface DatabaseTransaction {
  commit(): Promise<void>;
  rollback(): Promise<void>;
}

interface DatabaseConnection {
  query(sql: string, params?: any[]): Promise<any>;
  table(tableName: string): QueryBuilder;
}

interface QueryBuilder {
  insert(data: any): Promise<any>;
  select(...columns: string[]): this;
  where(column: string, value: any): this;
  first(): Promise<any>;
}

interface FileUploadOptions {
  filename: string;
  content: Buffer | string;
  mimeType: string;
  size?: number;
}

interface ApplicationService {
  container: Container;
  config: ConfigManager;
  env: Env;
  terminate(): Promise<void>;
}