{"id":17297,"library":"mountebank","title":"Mountebank: Over-the-Wire Test Doubles","description":"Mountebank is an open-source, cross-platform, multi-protocol test double tool designed to mock services over the wire. It enables developers to create configurable mock API endpoints for various protocols like HTTP, HTTPS, TCP, and SMTP. Mountebank primarily operates by creating \"imposters\" that listen on specified ports, responding to requests based on defined \"stubs\" which include predicates (conditions) and responses. This approach allows for isolated and repeatable testing of applications, reducing dependencies on external services and improving development efficiency.\nThe project recently transitioned to a community-driven effort under the `mountebank-testing` GitHub organization, with the npm package name changing from `mountebank` to `@mbtest/mountebank`. It maintains a consistent release cadence, with several updates in the past year (v2.9.1 to v2.9.4). Key differentiators include its multi-protocol support, a powerful REST API for dynamic configuration, and the ability to extend functionality through JavaScript injection.","status":"active","version":"2.9.1","language":"javascript","source_language":"en","source_url":"https://github.com/bbyars/mountebank","tags":["javascript","test","stub","mock","double","smtp","email","http","https"],"install":[{"cmd":"npm install mountebank","lang":"bash","label":"npm"},{"cmd":"yarn add mountebank","lang":"bash","label":"yarn"},{"cmd":"pnpm add mountebank","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Used for SMTP protocol mocking. Updated to v8 in mountebank v2.9.4.","package":"nodemailer","optional":false},{"reason":"Default formatter for configuration files. Made optional in mountebank v2.9.3.","package":"mountebank-formatters","optional":true}],"imports":[{"note":"The primary way to use Mountebank is via its command-line interface. The package name changed to `@mbtest/mountebank` in v2.9.2. Global installation makes the `mb` command available.","wrong":"npm install -g mountebank","symbol":"mb","correct":"npm install -g @mbtest/mountebank && mb"},{"note":"For programmatic control of the Mountebank server itself (e.g., starting/stopping), you can `require` the package. Ensure you use the new scoped package name `@mbtest/mountebank`.","wrong":"const mb = require('mountebank');","symbol":"mb.create","correct":"const mb = require('@mbtest/mountebank'); const server = await mb.create({ port: 2525 });"},{"note":"Programmatic creation and management of imposters (mock services) is typically done by sending HTTP requests to Mountebank's administration API, usually on port 2525 by default. No direct `import` for this, but standard HTTP client libraries are used.","wrong":null,"symbol":"Imposter API","correct":"fetch('http://localhost:2525/imposters', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(imposterConfig) })"}],"quickstart":{"code":"import { strict as assert } from 'assert';\nimport { exec } from 'child_process';\nimport util from 'util';\n\nconst execPromise = util.promisify(exec);\n\nconst imposterConfig = {\n  port: 4545,\n  protocol: 'http',\n  stubs: [\n    {\n      predicates: [{\n        equals: { path: '/test', method: 'GET' }\n      }],\n      responses: [\n        { is: { statusCode: 200, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ message: 'Hello from Mountebank!' }) } }\n      ]\n    }\n  ]\n};\n\nasync function runMountebankQuickstart() {\n  let mbProcess;\n  try {\n    console.log('1. Installing @mbtest/mountebank globally...');\n    await execPromise('npm install -g @mbtest/mountebank');\n    console.log('   Installed successfully.');\n\n    console.log('2. Starting Mountebank server...');\n    // Using `exec` to start mb in the background, ensure --allowInjection for future use cases\n    // and --loglevel debug for better visibility.\n    mbProcess = exec('mb --allowInjection --loglevel debug');\n    mbProcess.stdout.pipe(process.stdout);\n    mbProcess.stderr.pipe(process.stderr);\n\n    // Give Mountebank a moment to start up\n    await new Promise(resolve => setTimeout(resolve, 3000)); \n    console.log('   Mountebank server started (admin UI at http://localhost:2525).');\n\n    console.log('3. Creating an HTTP imposter...');\n    await fetch('http://localhost:2525/imposters', {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify(imposterConfig)\n    });\n    console.log('   Imposter created on port 4545.');\n\n    console.log('4. Testing the mocked service...');\n    const response = await fetch('http://localhost:4545/test');\n    const data = await response.json();\n\n    assert.equal(response.status, 200, 'Expected status code 200');\n    assert.deepEqual(data, { message: 'Hello from Mountebank!' }, 'Expected specific mock response');\n    console.log('   Mocked service responded correctly:', data);\n\n  } catch (error) {\n    console.error('An error occurred:', error.message);\n    process.exit(1);\n  } finally {\n    if (mbProcess) {\n      console.log('5. Stopping Mountebank server...');\n      // Terminate the mountebank process gracefully\n      await execPromise('mb stop');\n      console.log('   Mountebank server stopped.');\n    }\n  }\n}\n\nrunMountebankQuickstart();","lang":"javascript","description":"This quickstart demonstrates how to install Mountebank globally, start the `mb` server, programmatically create a simple HTTP GET imposter via its REST API, and then verify the mock response."},"warnings":[{"fix":"Update your `package.json` dependency to `\"@mbtest/mountebank\": \"^2.9.x\"` and reinstall. For global installs, use `npm install -g @mbtest/mountebank`.","message":"The official npm package name changed from `mountebank` to `@mbtest/mountebank` starting from version v2.9.2. Existing projects must update their `package.json` and installation commands (`npm install -g @mbtest/mountebank`).","severity":"breaking","affected_versions":">=2.9.2"},{"fix":"Upgrade your Node.js environment to version 20 or higher. For Docker deployments, use images based on Node 24 or later.","message":"Minimum Node.js version updated to 20 for core maintenance LTS in v2.9.4. Docker images now use Node 24 (active LTS). Running on older Node.js versions may lead to instability or failures.","severity":"breaking","affected_versions":">=2.9.4"},{"fix":"When starting Mountebank, either via CLI or programmatically, ensure the `--allowInjection` flag is included: `mb --allowInjection` or `mb.create({ allowInjection: true })` if using a client library.","message":"Using JavaScript injection (e.g., for dynamic responses or predicates) requires starting the Mountebank server with the `--allowInjection` flag. Without this flag, any imposter configuration using injection will fail with an 'invalid injection' error.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"To persist configurations, use `mb --configfile your-imposters.json` on startup, or `mb --datadir /path/to/data` to persist all changes automatically to disk. Programmatically, ensure imposters are recreated after a server restart.","message":"Mountebank is not persistent by default. All configured imposters and recorded requests are lost when the server restarts unless you explicitly save and reload them using configuration files or the `--datadir` / `--impostersRepository` options.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Change the conflicting port in your Mountebank configuration, or stop the other application using that port. For imposters, specify a different `port` in your imposter configuration. For the admin API, use `mb --port <newPort>`.","cause":"Mountebank's administration port (2525) or an imposter's port is already in use by another application.","error":"Error: listen EADDRINUSE :::2525"},{"fix":"Restart Mountebank with the `--allowInjection` command-line flag: `mb --allowInjection`.","cause":"You are attempting to use JavaScript injection in an imposter (e.g., in a response `inject` block or predicate `inject`) without enabling the feature.","error":"invalid injection"},{"fix":"Upgrade npm to version 3 or higher (`npm install -g npm@latest`). If stuck on npm v2, a workaround involves adding mountebank's top-level dependencies to your `package.json` and deleting `node_modules/mountebank/node_modules` between `npm install` and `npm shrinkwrap`.","cause":"Older versions of npm (v2) can have issues with `npm shrinkwrap` or `npm install` when `mountebank` (or `@mbtest/mountebank`) is a dependency, particularly due to deep dependency trees.","error":"npm ERR! cb() never called!"}],"ecosystem":"npm","meta_description":null}