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
Comprehensive mock cleanup and restoration utilities for maintaining test isolation and preventing test interference.
Restore all mocks globally across the entire testing environment.
/**
* Restore all mocks (enhanced version of mm.restore)
* @returns {Promise<void>} Promise that resolves when restoration is complete
*/
async mm.restore();Usage Examples:
// Global restoration in test teardown
describe('API tests', () => {
let app;
beforeEach(() => {
app = mm.app();
return app.ready();
});
afterEach(async () => {
await app.close();
await mm.restore(); // Restore all global mocks
});
it('should mock and restore environment', async () => {
mm.env('production');
mm.consoleLevel('DEBUG');
mm.home('/custom/home');
// Test with mocked environment
assert.equal(process.env.EGG_SERVER_ENV, 'production');
assert.equal(process.env.EGG_LOG, 'DEBUG');
assert.equal(process.env.EGG_HOME, '/custom/home');
// Restoration happens in afterEach
});
it('should have clean environment', async () => {
// Environment should be clean after previous test
assert(!process.env.EGG_MOCK_SERVER_ENV);
assert(!process.env.EGG_LOG);
assert(!process.env.EGG_HOME);
});
});Restore mocks specific to an application instance.
/**
* Restore all application-specific mocks
* @returns {Application} Application instance for chaining
*/
app.mockRestore();Usage Examples:
// Application-level restoration
describe('Service mocking tests', () => {
let app;
beforeEach(() => {
app = mm.app();
return app.ready();
});
afterEach(() => {
app.mockRestore(); // Restore app-level mocks
return app.close();
});
it('should mock and restore services', async () => {
app.mockService('user', 'find', { id: 123, name: 'Alice' });
app.mockSession({ userId: 123 });
app.mockCookies({ theme: 'dark' });
// Use mocked services
const user = await app.service.user.find(123);
assert.equal(user.name, 'Alice');
// Restoration happens in afterEach
});
it('should have clean services', async () => {
// Services should be restored after previous test
const user = await app.service.user.find(123);
// Should call real service, not mock
assert.notEqual(user.name, 'Alice');
});
});Restore mock HTTP agents and urllib interceptors.
/**
* Restore mock HTTP agent
* @returns {Promise<void>} Promise that resolves when agent is restored
*/
async app.mockAgentRestore();Usage Examples:
// HTTP agent restoration
describe('HTTP client tests', () => {
let app;
beforeEach(() => {
app = mm.app();
return app.ready();
});
afterEach(async () => {
await app.mockAgentRestore(); // Restore HTTP agent
await app.close();
});
it('should mock HTTP requests', async () => {
app.mockHttpclient('https://api.example.com/users', {
data: [{ id: 1, name: 'Alice' }]
});
// Make HTTP request through service
const users = await app.service.api.getUsers();
assert.equal(users[0].name, 'Alice');
// Agent restoration happens in afterEach
});
it('should make real HTTP requests', async () => {
// HTTP client should make real requests after restoration
try {
await app.service.api.getUsers();
// This will make a real HTTP request or fail with network error
} catch (error) {
// Expected if no real API available
assert(error.code === 'ENOTFOUND' || error.code === 'ECONNREFUSED');
}
});
});Restore mocks in cluster applications.
/**
* Restore cluster application mocks
*/
clusterApp.mockRestore();Usage Examples:
// Cluster restoration
describe('Cluster mock tests', () => {
let app;
before(function(done) {
app = mm.cluster({ baseDir: 'test/fixtures/apps/demo' });
app.ready(done);
});
after(function() {
return app.close();
});
afterEach(() => {
app.mockRestore(); // Restore cluster mocks
});
it('should mock in cluster mode', () => {
// Mock service in cluster
return app.mockService('user', 'find', { id: 123 })
.then(() => app.httpRequest()
.get('/api/user/123')
.expect(200)
.expect(res => {
assert.equal(res.body.id, 123);
})
);
});
it('should have restored cluster mocks', () => {
// Service should be restored in cluster
return app.httpRequest()
.get('/api/user/123')
.expect(res => {
// Should use real service, not mock
assert.notEqual(res.body.id, 123);
});
});
});Restore specific types of mocks while keeping others active.
Usage Examples:
// Selective restoration
describe('Selective restoration tests', () => {
let app;
beforeEach(() => {
app = mm.app();
return app.ready();
});
afterEach(() => {
return app.close();
});
it('should restore only HTTP mocks', async () => {
// Set up multiple mocks
mm.env('test');
app.mockService('user', 'find', { id: 123 });
app.mockHttpclient('https://api.example.com/data', { data: 'mock' });
// Restore only HTTP agent
await app.mockAgentRestore();
// Environment and service mocks should still be active
assert.equal(process.env.EGG_SERVER_ENV, 'test');
const user = await app.service.user.find(123);
assert.equal(user.id, 123);
// HTTP client should be restored
// (would make real request or fail)
// Clean up remaining mocks
app.mockRestore();
await mm.restore();
});
});Handle errors during mock restoration gracefully.
Usage Examples:
// Error handling in restoration
describe('Restoration error handling', () => {
let app;
beforeEach(() => {
app = mm.app();
return app.ready();
});
afterEach(async () => {
try {
await app.mockAgentRestore();
app.mockRestore();
await mm.restore();
} catch (error) {
console.error('Error during cleanup:', error);
// Continue with test cleanup despite errors
}
try {
await app.close();
} catch (error) {
console.error('Error closing app:', error);
}
});
it('should handle restoration errors gracefully', async () => {
// Set up mocks that might cause restoration issues
app.mockHttpclient('https://invalid-url', { data: 'test' });
// Test should pass regardless of restoration errors
const response = await app.httpRequest()
.get('/api/test')
.expect(200);
assert(response.body);
});
});Recommended patterns for mock restoration in different testing scenarios.
Usage Examples:
// Best practice: Global restoration utility
function setupMockRestore() {
afterEach(async () => {
// Always restore in this order for clean teardown
if (global.currentApp) {
await global.currentApp.mockAgentRestore().catch(() => {});
global.currentApp.mockRestore();
await global.currentApp.close();
global.currentApp = null;
}
await mm.restore();
});
}
// Usage across test files
describe('User API tests', () => {
setupMockRestore();
beforeEach(() => {
global.currentApp = mm.app();
return global.currentApp.ready();
});
it('should create user', async () => {
global.currentApp.mockService('user', 'create', { id: 123 });
// Test implementation
});
});
// Best practice: Restoration verification
describe('Mock restoration verification', () => {
it('should fully restore environment', async () => {
// Save original state
const originalEnv = process.env.NODE_ENV;
const originalEggEnv = process.env.EGG_SERVER_ENV;
// Apply mocks
mm.env('production');
mm.consoleLevel('DEBUG');
// Verify mocks are applied
assert.equal(process.env.EGG_SERVER_ENV, 'production');
assert.equal(process.env.EGG_LOG, 'DEBUG');
// Restore
await mm.restore();
// Verify complete restoration
assert.equal(process.env.NODE_ENV, originalEnv);
assert(!process.env.EGG_SERVER_ENV || process.env.EGG_SERVER_ENV === originalEggEnv);
assert(!process.env.EGG_LOG);
assert(!process.env.EGG_HOME);
});
});
// Best practice: Nested restoration
describe('Nested test suites', () => {
// Outer suite restoration
afterEach(async () => {
await mm.restore();
});
describe('Service tests', () => {
let app;
beforeEach(() => {
app = mm.app();
return app.ready();
});
afterEach(() => {
app.mockRestore();
return app.close();
});
it('should handle nested restoration', async () => {
mm.env('test');
app.mockService('test', 'method', 'result');
// Both app.mockRestore() and mm.restore() will be called
// in the correct order due to nested afterEach
});
});
});Set up automatic restoration using test framework hooks.
Usage Examples:
// Mocha hooks for automatic restoration
let globalApp;
// Global hooks
before(() => {
// Global test setup
});
after(async () => {
// Global test teardown
await mm.restore();
});
beforeEach(() => {
globalApp = mm.app();
return globalApp.ready();
});
afterEach(async () => {
if (globalApp) {
await globalApp.mockAgentRestore().catch(() => {});
globalApp.mockRestore();
await globalApp.close();
globalApp = null;
}
});
// Jest hooks for automatic restoration
beforeEach(async () => {
global.testApp = mm.app();
await global.testApp.ready();
});
afterEach(async () => {
if (global.testApp) {
await global.testApp.mockAgentRestore();
global.testApp.mockRestore();
await global.testApp.close();
global.testApp = null;
}
await mm.restore();
});Install with Tessl CLI
npx tessl i tessl/npm-egg-mock