or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

application-creation.mdcontext-session-mocking.mdenvironment-configuration.mdhttp-client-mocking.mdhttp-testing-utilities.mdindex.mdlogging-assertions.mdmock-restoration.mdservice-mocking.md
tile.json

http-testing-utilities.mddocs/

HTTP Testing Utilities

Supertest integration and enhanced testing utilities for making HTTP requests with custom assertion methods and comprehensive test coverage.

Capabilities

HTTP Request Testing

Create supertest-compatible request instances for testing HTTP endpoints.

/**
 * Create supertest request instance
 * @returns {SupertestRequest} HTTP testing object with methods for all HTTP verbs
 */
app.httpRequest();

interface SupertestRequest {
  /** Make GET request */
  get(url: string): EggTest;
  /** Make POST request */
  post(url: string): EggTest;
  /** Make PUT request */
  put(url: string): EggTest;
  /** Make DELETE request */
  delete(url: string): EggTest;
  /** Make PATCH request */
  patch(url: string): EggTest;
  /** Make HEAD request */
  head(url: string): EggTest;
  /** Make OPTIONS request */
  options(url: string): EggTest;
  /** Make TRACE request */
  trace(url: string): EggTest;
  /** Make CONNECT request */
  connect(url: string): EggTest;
}

type Methods = 'get' | 'post' | 'delete' | 'del' | 'put' | 'head' | 'options' | 'patch' | 'trace' | 'connect';

Usage Examples:

// Basic HTTP testing
describe('API endpoints', () => {
  let app;
  
  before(() => {
    app = mm.app();
    return app.ready();
  });
  
  after(() => app.close());

  it('should GET /', () => {
    return app.httpRequest()
      .get('/')
      .expect(200)
      .expect('Content-Type', /html/);
  });

  it('should POST /api/users', () => {
    return app.httpRequest()
      .post('/api/users')
      .send({ name: 'Alice', email: 'alice@example.com' })
      .expect(201)
      .expect('Content-Type', /json/)
      .expect(res => {
        assert(res.body.id);
        assert.equal(res.body.name, 'Alice');
      });
  });
});

Enhanced Test Interface

Extended supertest interface with additional assertion methods specific to Egg.js testing.

interface EggTest extends Test {
  /**
   * Assert that response does not contain specified header
   * @param {string} name - Header name to check for absence
   * @param {Function} [callback] - Optional callback function
   * @returns {EggTest} Test instance for chaining
   */
  unexpectHeader(name: string, callback?: Function): EggTest;
  
  /**
   * Assert that response contains specified header
   * @param {string} name - Header name to check for presence
   * @param {Function} [callback] - Optional callback function  
   * @returns {EggTest} Test instance for chaining
   */
  expectHeader(name: string, callback?: Function): EggTest;
}

Usage Examples:

// Header presence testing
it('should have security headers', () => {
  return app.httpRequest()
    .get('/secure')
    .expect(200)
    .expectHeader('x-frame-options')
    .expectHeader('x-content-type-options')
    .unexpectHeader('x-powered-by');
});

// Header value testing
it('should set correct content type', () => {
  return app.httpRequest()
    .get('/api/data')
    .expect(200)
    .expectHeader('content-type', /application\/json/)
    .unexpectHeader('set-cookie');
});

// Custom header assertions
it('should have rate limit headers', () => {
  return app.httpRequest()
    .get('/api/limited')
    .expect(200)
    .expectHeader('x-ratelimit-limit')
    .expectHeader('x-ratelimit-remaining')
    .expect(res => {
      const limit = parseInt(res.headers['x-ratelimit-limit']);
      const remaining = parseInt(res.headers['x-ratelimit-remaining']);
      assert(limit > 0);
      assert(remaining >= 0);
      assert(remaining <= limit);
    });
});

Request Body and Data Testing

Send various types of request data and test request handling.

Usage Examples:

// JSON request body
it('should handle JSON data', () => {
  return app.httpRequest()
    .post('/api/data')
    .send({ 
      name: 'Test Item',
      value: 123,
      active: true 
    })
    .expect(201)
    .expect('Content-Type', /json/)
    .expect(res => {
      assert.equal(res.body.name, 'Test Item');
      assert.equal(res.body.value, 123);
    });
});

// Form data
it('should handle form data', () => {
  return app.httpRequest()
    .post('/submit')
    .type('form')
    .send({ username: 'alice', password: 'secret' })
    .expect(302)
    .expect('Location', '/dashboard');
});

// File upload simulation
it('should handle file upload', () => {
  return app.httpRequest()
    .post('/upload')
    .attach('file', Buffer.from('file content'), 'test.txt')
    .field('description', 'Test file')
    .expect(200)
    .expect(res => {
      assert.equal(res.body.filename, 'test.txt');
      assert.equal(res.body.size, 12);
    });
});

// Query parameters
it('should handle query parameters', () => {
  return app.httpRequest()
    .get('/search')
    .query({ q: 'test', limit: 10, offset: 0 })
    .expect(200)
    .expect(res => {
      assert.equal(res.body.query, 'test');
      assert.equal(res.body.results.length, 10);
    });
});

Authentication Testing

Test various authentication mechanisms and protected endpoints.

Usage Examples:

// Bearer token authentication
it('should require authentication', () => {
  return app.httpRequest()
    .get('/api/protected')
    .expect(401);
});

it('should accept valid token', () => {
  return app.httpRequest()
    .get('/api/protected')
    .set('Authorization', 'Bearer valid-token')
    .expect(200)
    .expect(res => {
      assert(res.body.user);
      assert.equal(res.body.user.authenticated, true);
    });
});

// Basic authentication
it('should handle basic auth', () => {
  return app.httpRequest()
    .get('/api/basic')
    .auth('username', 'password')
    .expect(200);
});

// Session-based authentication
it('should handle session auth', () => {
  return app.httpRequest()
    .post('/login')
    .send({ username: 'alice', password: 'secret' })
    .expect(302)
    .then(res => {
      const cookies = res.headers['set-cookie'];
      return app.httpRequest()
        .get('/dashboard')
        .set('Cookie', cookies)
        .expect(200);
    });
});

// CSRF token testing
it('should handle CSRF protection', () => {
  // Get CSRF token
  return app.httpRequest()
    .get('/form')
    .expect(200)
    .then(res => {
      const token = res.body.csrfToken;
      // Use token in POST request
      return app.httpRequest()
        .post('/api/action')
        .send({ data: 'test', _csrf: token })
        .expect(200);
    });
});

Error Response Testing

Test error handling and error response formats.

Usage Examples:

// Test error status codes
it('should return 404 for missing resource', () => {
  return app.httpRequest()
    .get('/api/users/nonexistent')
    .expect(404)
    .expect('Content-Type', /json/)
    .expect(res => {
      assert.equal(res.body.error, 'User not found');
    });
});

// Test validation errors
it('should validate required fields', () => {
  return app.httpRequest()
    .post('/api/users')
    .send({ email: 'invalid-email' })
    .expect(400)
    .expect(res => {
      assert(res.body.errors);
      assert(res.body.errors.name);
      assert(res.body.errors.email);
    });
});

// Test server errors
it('should handle server errors gracefully', () => {
  // Mock service to throw error
  app.mockServiceError('user', 'create', 'Database connection failed');
  
  return app.httpRequest()
    .post('/api/users')
    .send({ name: 'Alice', email: 'alice@example.com' })
    .expect(500)
    .expect(res => {
      assert.equal(res.body.error, 'Internal server error');
    });
});

Content Type Testing

Test different content types and response formats.

Usage Examples:

// JSON API testing
it('should return JSON', () => {
  return app.httpRequest()
    .get('/api/data')
    .expect(200)
    .expect('Content-Type', /application\/json/)
    .expect(res => {
      assert(typeof res.body === 'object');
    });
});

// XML response testing
it('should return XML', () => {
  return app.httpRequest()
    .get('/api/data.xml')
    .expect(200)
    .expect('Content-Type', /application\/xml/)
    .expect(res => {
      assert(typeof res.text === 'string');
      assert(res.text.includes('<?xml'));
    });
});

// Plain text response
it('should return plain text', () => {
  return app.httpRequest()
    .get('/health')
    .expect(200)
    .expect('Content-Type', /text\/plain/)
    .expect('OK');
});

// HTML response
it('should return HTML', () => {
  return app.httpRequest()
    .get('/')
    .expect(200)
    .expect('Content-Type', /text\/html/)
    .expect(res => {
      assert(res.text.includes('<html>'));
    });
});

Cluster Application HTTP Testing

HTTP testing specifically for cluster applications with supertest compatibility.

/**
 * Create supertest request for cluster testing
 * @returns {SupertestRequest} HTTP testing object for cluster
 */
clusterApp.httpRequest();

Usage Examples:

// Cluster application testing
describe('ClusterApplication HTTP', () => {
  let app;
  
  before(function(done) {
    app = mm.cluster({ baseDir: 'test/fixtures/apps/demo' });
    app.ready(done);
  });
  
  after(function() {
    return app.close();
  });

  it('should handle requests in cluster mode', () => {
    return app.httpRequest()
      .get('/api/cluster-info')
      .expect(200)
      .expect(res => {
        assert(res.body.pid);
        assert(res.body.workers);
      });
  });

  it('should handle concurrent requests', async () => {
    const requests = Array.from({ length: 10 }, (_, i) => 
      app.httpRequest()
        .get(`/api/data/${i}`)
        .expect(200)
    );
    
    const responses = await Promise.all(requests);
    responses.forEach((res, i) => {
      assert.equal(res.body.id, i);
    });
  });
});

Custom Assertion Helpers

Create custom assertion helpers for common testing patterns.

Usage Examples:

// Custom helper for API responses
function expectApiSuccess(test) {
  return test
    .expect(200)
    .expect('Content-Type', /json/)
    .expect(res => {
      assert.equal(res.body.success, true);
      assert(res.body.data);
    });
}

// Usage
it('should return successful API response', () => {
  return expectApiSuccess(
    app.httpRequest().get('/api/success')
  );
});

// Custom helper for paginated responses
function expectPaginatedResponse(test, expectedPage = 1) {
  return test
    .expect(200)
    .expect(res => {
      assert(res.body.data);
      assert(Array.isArray(res.body.data));
      assert.equal(res.body.page, expectedPage);
      assert(typeof res.body.total === 'number');
    });
}

// Usage
it('should return paginated users', () => {
  return expectPaginatedResponse(
    app.httpRequest().get('/api/users?page=2'),
    2
  );
});