Mock testing library for Egg.js applications with comprehensive mocking capabilities for HTTP, services, contexts, and testing utilities
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Log collection, monitoring, and assertion utilities for testing log output with pattern matching and multi-logger support.
Start collecting logger messages for testing and verification purposes.
/**
* Start collecting logger messages for testing
* @param {string|Logger} [logger] - Logger instance or name (defaults to app.logger)
*/
app.mockLog(logger);
/**
* Collection logger message in cluster mode
* @param {string} [logger] - Logger name (defaults to 'logger')
*/
clusterApp.mockLog(logger);Usage Examples:
// Basic log collection
describe('logging tests', () => {
let app;
beforeEach(() => {
app = mm.app();
return app.ready();
});
afterEach(() => app.close());
it('should collect default logger messages', async () => {
app.mockLog(); // Start collecting app.logger messages
// Trigger some logging
await app.httpRequest()
.get('/api/test')
.expect(200);
app.expectLog('Request processed successfully');
});
// Named logger collection
it('should collect specific logger messages', async () => {
app.mockLog('accessLogger'); // Collect specific logger
await app.httpRequest()
.get('/api/users')
.expect(200);
app.expectLog('GET /api/users', 'accessLogger');
});
});Assert the presence or absence of specific log messages and patterns.
/**
* Assert that a string/pattern exists in logs
* @param {string|RegExp} str - String or pattern to find
* @param {string|Logger} [logger] - Logger instance or name
*/
app.expectLog(str, logger);
/**
* Assert that a string/pattern does not exist in logs
* @param {string|RegExp} str - String or pattern that should not be found
* @param {string|Logger} [logger] - Logger instance or name
*/
app.notExpectLog(str, logger);
/**
* Cluster mode log assertions (string-only)
* @param {string} str - String to find in logs
* @param {string} [logger] - Logger name
*/
clusterApp.expectLog(str, logger);
clusterApp.notExpectLog(str, logger);Usage Examples:
// String matching
it('should log user creation', async () => {
app.mockLog();
await app.httpRequest()
.post('/api/users')
.send({ name: 'Alice' })
.expect(201);
app.expectLog('User created: Alice');
app.notExpectLog('Error creating user');
});
// RegExp pattern matching
it('should log request timing', async () => {
app.mockLog();
await app.httpRequest()
.get('/api/slow-endpoint')
.expect(200);
app.expectLog(/Request completed in \d+ms/);
app.notExpectLog(/Error:/);
});
// Multiple logger testing
it('should log to different loggers', async () => {
app.mockLog('app');
app.mockLog('access');
app.mockLog('error');
await app.httpRequest()
.post('/api/invalid')
.send({ invalid: 'data' })
.expect(400);
app.expectLog('Validation failed', 'app');
app.expectLog('POST /api/invalid 400', 'access');
app.expectLog('Invalid request data', 'error');
});Test custom loggers and logger configurations.
Usage Examples:
// Custom logger instance
it('should use custom logger', async () => {
const customLogger = app.getLogger('custom');
app.mockLog(customLogger);
// Code that uses custom logger
customLogger.info('Custom operation started');
customLogger.info('Custom operation completed');
app.expectLog('Custom operation started', customLogger);
app.expectLog('Custom operation completed', customLogger);
});
// Logger with different levels
it('should capture different log levels', async () => {
app.mockLog();
app.logger.debug('Debug message');
app.logger.info('Info message');
app.logger.warn('Warning message');
app.logger.error('Error message');
app.expectLog('Debug message');
app.expectLog('Info message');
app.expectLog('Warning message');
app.expectLog('Error message');
});
// Conditional logging based on environment
it('should log based on environment', async () => {
app.mockEnv('development');
app.mockLog();
// Code that logs differently in development
if (app.config.env === 'development') {
app.logger.debug('Development debug info');
}
app.expectLog('Development debug info');
});Specifically test error logging and exception handling.
Usage Examples:
// Exception logging
it('should log exceptions', async () => {
app.mockLog();
app.mockServiceError('user', 'find', new Error('Database connection failed'));
await app.httpRequest()
.get('/api/users/123')
.expect(500);
app.expectLog('Database connection failed');
app.expectLog(/Error in user\.find/);
});
// Custom error logging
it('should log validation errors', async () => {
app.mockLog();
await app.httpRequest()
.post('/api/users')
.send({ email: 'invalid-email' })
.expect(400);
app.expectLog('Validation error');
app.expectLog('Invalid email format');
app.notExpectLog('User created successfully');
});
// Stack trace logging
it('should include stack traces in error logs', async () => {
app.mockLog();
const error = new Error('Test error');
app.mockServiceError('test', 'method', error);
try {
await app.service.test.method();
} catch (e) {
// Error should be logged with stack trace
}
app.expectLog('Test error');
app.expectLog(/at.*test.*method/); // Stack trace pattern
});Test performance-related logging and request timing.
Usage Examples:
// Request timing logs
it('should log request timing', async () => {
app.mockLog();
await app.httpRequest()
.get('/api/data')
.expect(200);
app.expectLog(/GET \/api\/data.*\d+ms/);
});
// Slow request warnings
it('should warn about slow requests', async () => {
app.mockLog();
// Mock slow service
app.mockService('data', 'fetch', async () => {
await new Promise(resolve => setTimeout(resolve, 1000));
return { data: 'slow response' };
});
await app.httpRequest()
.get('/api/slow')
.expect(200);
app.expectLog(/Slow request detected.*1\d{3}ms/);
});
// Database query timing
it('should log database query performance', async () => {
app.mockLog('sqlLogger');
await app.httpRequest()
.get('/api/users')
.expect(200);
app.expectLog(/SELECT.*FROM users.*\d+ms/, 'sqlLogger');
});Test structured logging with JSON objects and metadata.
Usage Examples:
// JSON log entries
it('should log structured data', async () => {
app.mockLog();
app.logger.info('User action', {
userId: 123,
action: 'login',
ip: '192.168.1.1',
userAgent: 'test-client'
});
app.expectLog('User action');
app.expectLog(/"userId":123/);
app.expectLog(/"action":"login"/);
});
// Log metadata verification
it('should include request metadata in logs', async () => {
app.mockLog();
await app.httpRequest()
.get('/api/users')
.set('x-request-id', 'req-123')
.expect(200);
app.expectLog(/"requestId":"req-123"/);
app.expectLog(/"method":"GET"/);
app.expectLog(/"url":"\/api\/users"/);
});Test logging to files and file-based log assertions.
Usage Examples:
// File-based log testing (when not using mockLog)
it('should write to log file', async () => {
// Don't call mockLog to test file-based logging
await app.httpRequest()
.get('/api/test')
.expect(200);
// expectLog will read from file when no mockLog was called
app.expectLog('Request completed');
});
// Multiple log files
it('should write to different log files', async () => {
await app.httpRequest()
.post('/api/error-prone')
.send({ invalid: 'data' })
.expect(400);
// Check application log
app.expectLog('Validation failed', 'app');
// Check error log
app.expectLog('Request failed', 'errorLogger');
});Specific logging tests for cluster applications.
Usage Examples:
// Cluster application logging
describe('Cluster logging', () => {
let app;
before(function(done) {
app = mm.cluster({ baseDir: 'test/fixtures/apps/demo' });
app.ready(done);
});
after(function() {
return app.close();
});
it('should log in cluster mode', () => {
app.mockLog(); // Cluster mode
return app.httpRequest()
.get('/api/cluster-test')
.expect(200)
.then(() => {
app.expectLog('Cluster request processed');
});
});
it('should log worker information', () => {
app.mockLog();
return app.httpRequest()
.get('/api/worker-info')
.expect(200)
.then(() => {
app.expectLog(/Worker PID: \d+/);
});
});
});Install with Tessl CLI
npx tessl i tessl/npm-egg-mock