CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-egg-mock

Mock testing library for Egg.js applications with comprehensive mocking capabilities for HTTP, services, contexts, and testing utilities

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

mock-restoration.mddocs/

Mock Restoration

Comprehensive mock cleanup and restoration utilities for maintaining test isolation and preventing test interference.

Capabilities

Global Mock Restoration

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);
  });
});

Application Mock Restoration

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');
  });
});

HTTP Agent Restoration

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');
    }
  });
});

Cluster Mock Restoration

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);
      });
  });
});

Selective Mock Restoration

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();
  });
});

Restoration Error Handling

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);
  });
});

Restoration Best Practices

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
    });
  });
});

Automatic Restoration with Hooks

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

docs

application-creation.md

context-session-mocking.md

environment-configuration.md

http-client-mocking.md

http-testing-utilities.md

index.md

logging-assertions.md

mock-restoration.md

service-mocking.md

tile.json