Supertest integration and enhanced testing utilities for making HTTP requests with custom assertion methods and comprehensive test coverage.
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');
});
});
});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);
});
});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);
});
});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);
});
});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');
});
});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>'));
});
});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);
});
});
});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
);
});