{"id":13521257,"url":"https://github.com/mocktools/ruby-smtp-mock","last_synced_at":"2025-04-05T00:10:35.382Z","repository":{"id":40258921,"uuid":"443795043","full_name":"mocktools/ruby-smtp-mock","owner":"mocktools","description":"💎 Ruby SMTP mock. Mimic any 📤 SMTP server behavior for your test environment with fake SMTP server.","archived":false,"fork":false,"pushed_at":"2024-10-29T14:33:13.000Z","size":172,"stargazers_count":65,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-28T23:06:01.662Z","etag":null,"topics":["fake-server","fake-smtp-server","hacktoberfest","mock","mock-server","mocktools","rspec","ruby","ruby-gem","smtp","smtp-fake","smtp-mail","smtp-mock","smtp-server","testing","testing-tools"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mocktools.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["bestwebua"]}},"created_at":"2022-01-02T15:06:08.000Z","updated_at":"2025-03-18T21:49:02.000Z","dependencies_parsed_at":"2023-02-14T17:01:43.540Z","dependency_job_id":"6cbd25ad-ac9a-4c92-8430-9866c851b855","html_url":"https://github.com/mocktools/ruby-smtp-mock","commit_stats":{"total_commits":73,"total_committers":1,"mean_commits":73.0,"dds":0.0,"last_synced_commit":"a2efeddc824d37def7429b0b5bea517ef5251906"},"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mocktools%2Fruby-smtp-mock","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mocktools%2Fruby-smtp-mock/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mocktools%2Fruby-smtp-mock/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mocktools%2Fruby-smtp-mock/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mocktools","download_url":"https://codeload.github.com/mocktools/ruby-smtp-mock/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247266565,"owners_count":20910836,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fake-server","fake-smtp-server","hacktoberfest","mock","mock-server","mocktools","rspec","ruby","ruby-gem","smtp","smtp-fake","smtp-mail","smtp-mock","smtp-server","testing","testing-tools"],"created_at":"2024-08-01T06:00:31.763Z","updated_at":"2025-04-05T00:10:35.362Z","avatar_url":"https://github.com/mocktools.png","language":"Ruby","funding_links":["https://github.com/sponsors/bestwebua"],"categories":["Ruby","Testing","Mocks"],"sub_categories":[],"readme":"# ![Ruby SmtpMock - mimic any 📤 SMTP server behavior for your test environment with fake SMTP server](https://repository-images.githubusercontent.com/443795043/81ce5b00-0915-4dd0-93ad-88e6699e18cd)\n\n[![Maintainability](https://api.codeclimate.com/v1/badges/315c5fff7449a11868dd/maintainability)](https://codeclimate.com/github/mocktools/ruby-smtp-mock/maintainability)\n[![Test Coverage](https://api.codeclimate.com/v1/badges/315c5fff7449a11868dd/test_coverage)](https://codeclimate.com/github/mocktools/ruby-smtp-mock/test_coverage)\n[![CircleCI](https://circleci.com/gh/mocktools/ruby-smtp-mock/tree/master.svg?style=svg)](https://circleci.com/gh/mocktools/ruby-smtp-mock/tree/master)\n[![Gem Version](https://badge.fury.io/rb/smtp_mock.svg)](https://badge.fury.io/rb/smtp_mock)\n[![Downloads](https://img.shields.io/gem/dt/smtp_mock.svg?colorA=004d99\u0026colorB=0073e6)](https://rubygems.org/gems/smtp_mock)\n[![In Awesome Ruby](https://raw.githubusercontent.com/sindresorhus/awesome/main/media/mentioned-badge.svg)](https://github.com/markets/awesome-ruby)\n[![GitHub](https://img.shields.io/github/license/mocktools/ruby-smtp-mock)](LICENSE.txt)\n[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v1.4%20adopted-ff69b4.svg)](CODE_OF_CONDUCT.md)\n\n💎 Ruby SMTP mock - flexible Ruby wrapper over [`smtpmock`](https://github.com/mocktools/go-smtp-mock). Mimic any 📤 SMTP server behavior for your test environment and even more.\n\n## Table of Contents\n\n- [Features](#features)\n- [Requirements](#requirements)\n- [Installation](#installation)\n- [Usage](#usage)\n  - [Dependency manager](#dependency-manager)\n    - [Available flags](#available-flags)\n  - [DSL](#dsl)\n    - [Available server options](#available-server-options)\n    - [Example of usage](#example-of-usage)\n  - [RSpec integration](#rspec-integration)\n    - [SmtpMock RSpec helper](#smtpmock-rspec-helper)\n    - [SmtpMock RSpec interface](#smtpmock-rspec-interface)\n- [Contributing](#contributing)\n- [License](#license)\n- [Code of Conduct](#code-of-conduct)\n- [Credits](#credits)\n- [Versioning](#versioning)\n- [Changelog](CHANGELOG.md)\n\n## Features\n\n- Ability to handle configurable behavior and life cycles of SMTP mock server(s)\n- Dynamic/manual port assignment\n- Test framework agnostic (it's PORO, so you can use it outside of `RSpec`, `Test::Unit` or `MiniTest`)\n- Simple and intuitive DSL\n- RSpec integration out of the box\n- Includes easy system dependency manager\n\n## Requirements\n\nRuby MRI 2.5.0+\n\n## Installation\n\nAdd this line to your application's `Gemfile`:\n\n```ruby\ngroup :development, :test do\n  gem 'smtp_mock', require: false\nend\n```\n\nAnd then execute:\n\n```bash\nbundle\n```\n\nOr install it yourself as:\n\n```bash\ngem install smtp_mock\n```\n\nThen install [`smtpmock`](https://github.com/mocktools/go-smtp-mock) as system dependency:\n\n```bash\nbundle exec smtp_mock -i ~\n```\n\n## Usage\n\n### Dependency manager\n\nThis gem includes easy system dependency manager. Run `bundle exec smtp_mock` with options for manage `smtpmock` system dependency.\n\n#### Available flags\n\n| Flag | Description | Example of usage |\n| --- | --- | --- |\n| `-s`, `--sudo` | Run command as sudo | `bundle exec smtp_mock -s -i ~` |\n| `-i`, `--install=PATH` | Install `smtpmock` to the existing path | `bundle exec smtp_mock -i ~/existent_dir` |\n| `-u`, `--uninstall` | Uninstall `smtpmock` | `bundle exec smtp_mock -u` |\n| `-g`, `--upgrade` | Upgrade to latest version of `smtpmock` | `bundle exec smtp_mock -g` |\n| `-v`, `--version` | Prints current version of `smtpmock` | `bundle exec smtp_mock -v` |\n| `-h`, `--help` | Prints help | `bundle exec smtp_mock -h` |\n\n### DSL\n\n#### Available server options\n\n| Example of usage kwarg | Description |\n| --- | --- |\n| `host: '0.0.0.0'` | Host address where `smtpmock` will run. It's equal to 127.0.0.1 by default |\n| `port: 2525` | Server port number. If not specified it will be assigned dynamically |\n| `log: true` | Enables log server activity. Disabled by default |\n| `session_timeout: 60` | Session timeout in seconds. It's equal to 30 seconds by default |\n| `shutdown_timeout: 5` | Graceful shutdown timeout in seconds. It's equal to 1 second by default |\n| `fail_fast: true` | Enables fail fast scenario. Disabled by default |\n| `multiple_rcptto: true` | Enables multiple `RCPT TO` receiving scenario. Disabled by default |\n| `multiple_message_receiving: true` | Enables multiple message receiving scenario. Disabled by default |\n| `blacklisted_helo_domains: %w[a.com b.com]` | Blacklisted `HELO` domains |\n| `blacklisted_mailfrom_emails: %w[a@a.com b@b.com]` | Blacklisted `MAIL FROM` emails |\n| `blacklisted_rcptto_emails: %w[c@c.com d@d.com]` | blacklisted `RCPT TO` emails |\n| `not_registered_emails: %w[e@e.com f@f.com]` | Not registered (non-existent) `RCPT TO` emails |\n| `response_delay_helo: 2` | `HELO` response delay in seconds. It's equal to 0 seconds by default |\n| `response_delay_mailfrom: 2` | `MAIL FROM` response delay in seconds. It's equal to 0 seconds by default |\n| `response_delay_rcptto: 2` | `RCPT TO` response delay in seconds. It's equal to 0 seconds by default |\n| `response_delay_data: 2` | `DATA` response delay in seconds. It's equal to 0 seconds by default |\n| `response_delay_message: 2` | Message response delay in seconds. It's equal to 0 seconds by default |\n| `response_delay_rset: 2` | `RSET` response delay in seconds. It's equal to 0 seconds by default |\n| `response_delay_quit: 2` | `QUIT` response delay in seconds. It's equal to 0 seconds by default |\n| `msg_size_limit: 42` | Message body size limit in bytes. It's equal to 10485760 bytes by default |\n| `msg_greeting: 'Greeting message'` | Custom server greeting message |\n| `msg_invalid_cmd: 'Invalid command message'` | Custom invalid command message |\n| `msg_invalid_cmd_helo_sequence: 'Invalid command HELO sequence message'` | Custom invalid command `HELO` sequence message |\n| `msg_invalid_cmd_helo_arg: 'Invalid command HELO argument message'` | Custom invalid command `HELO` argument message |\n| `msg_helo_blacklisted_domain: 'Blacklisted domain message'` | Custom `HELO` blacklisted domain message |\n| `msg_helo_received: 'HELO received message'` | Custom `HELO` received message |\n| `msg_invalid_cmd_mailfrom_sequence: 'Invalid command MAIL FROM sequence message'` | Custom invalid command `MAIL FROM` sequence message |\n| `msg_invalid_cmd_mailfrom_arg: 'Invalid command MAIL FROM argument message'` | Custom invalid command `MAIL FROM` argument message |\n| `msg_mailfrom_blacklisted_email: 'Blacklisted email message'` | Custom `MAIL FROM` blacklisted email message |\n| `msg_mailfrom_received: 'MAIL FROM received message'` | Custom `MAIL FROM` received message |\n| `msg_invalid_cmd_rcptto_sequence: 'Invalid command RCPT TO sequence message'` | Custom invalid command `RCPT TO` sequence message |\n| `msg_invalid_cmd_rcptto_arg: 'Invalid command RCPT TO argument message'` | Custom invalid command `RCPT TO` argument message |\n| `msg_rcptto_not_registered_email: 'Not registered email message'` | Custom `RCPT TO` not registered email message |\n| `msg_rcptto_blacklisted_email: 'Blacklisted email message'` | Custom `RCPT TO` blacklisted email message |\n| `msg_rcptto_received: 'RCPT TO received message'` | Custom `RCPT TO` received message |\n| `msg_invalid_cmd_data_sequence: 'Invalid command DATA sequence message'` | Custom invalid command `DATA` sequence message |\n| `msg_data_received: 'DATA received message'` | Custom `DATA` received message |\n| `msg_msg_size_is_too_big: 'Message size is too big'` | Custom size is too big message |\n| `msg_invalid_cmd_rset_sequence: 'Invalid command RSET sequence message'` | Custom invalid command `RSET` sequence message |\n| `msg_invalid_cmd_rset_arg: 'Invalid command RSET argument message'` | Custom invalid command `RSET` argument message |\n| `msg_rset_received: 'RSET received message'` | Custom `RSET` received message |\n| `msg_quit_cmd: 'Quit command message'` | Custom quit command message |\n\n#### Example of usage\n\n```ruby\n# Public SmtpMock interface\n# Without kwargs creates SMTP mock server with default behavior.\n# A free port for server will be randomly assigned in the range\n# from 49152 to 65535. Returns current smtp mock server instance\nsmtp_mock_server = SmtpMock.start_server(not_registered_emails: %w[user@example.com]) # =\u003e SmtpMock::Server instance\n\n# returns current smtp mock server port\nsmtp_mock_server.port # =\u003e 55640\n\n# returns current smtp mock server process identification number (PID)\nsmtp_mock_server.pid # =\u003e 38195\n\n# returns current smtp mock server version\nsmtp_mock_server.version # =\u003e '1.5.2'\n\n# interface for graceful shutdown current smtp mock server\nsmtp_mock_server.stop # =\u003e true\n\n# interface for force shutdown current smtp mock server\nsmtp_mock_server.stop! # =\u003e true\n\n# interface to check state of current smtp mock server\n# returns true if server is running, otherwise returns false\nsmtp_mock_server.active? # =\u003e true\n\n# returns list of running smtp mock servers\nSmtpMock.running_servers # =\u003e [SmtpMock::Server instance]\n\n# interface to stop all running smtp mock servers\nSmtpMock.stop_running_servers! # =\u003e true\n```\n\n### RSpec integration\n\nRequire this either in your Gemfile or in RSpec's support scripts. So either:\n\n```ruby\n# Gemfile\n\ngroup :test do\n  gem 'rspec'\n  gem 'smtp_mock', require: 'smtp_mock/test_framework/rspec'\nend\n```\n\nor\n\n```ruby\n# spec/support/config/smtp_mock.rb\n\nrequire 'smtp_mock/test_framework/rspec'\n```\n\n#### SmtpMock RSpec helper\n\nJust add `SmtpMock::TestFramework::RSpec::Helper` if you wanna use shortcut `smtp_mock_server` for SmtpMock server instance inside of your `RSpec.describe` blocks:\n\n```ruby\n# spec/support/config/smtp_mock.rb\n\nRSpec.configure do |config|\n  config.include SmtpMock::TestFramework::RSpec::Helper\nend\n```\n\n```ruby\n# your awesome smtp_client_spec.rb\n\nRSpec.describe SmtpClient do\n  subject(:smtp_response) do\n    described_class.call(\n      host: 'localhost',\n      port: smtp_mock_server.port,\n      mailfrom: mailfrom,\n      rcptto: rcptto,\n      message: message\n    )\n  end\n\n  let(:mailfrom) { 'sender@example.com' }\n  let(:rcptto) { 'receiver@example.com' }\n  let(:message) { 'Email message context' }\n  let(:expected_response_message) { '250 Custom successful response' }\n\n  before { smtp_mock_server(msg_msg_received: expected_response_message) }\n\n  it do\n    expect(smtp_response).to be_success\n    expect(smtp_response).to have_status(expected_response_status)\n    expect(smtp_response).to have_message_context(expected_response_message)\n  end\nend\n```\n\n#### SmtpMock RSpec interface\n\nIf you won't use `SmtpMock::TestFramework::RSpec::Helper` you can use `SmtpMock::TestFramework::RSpec::Interface` directly instead:\n\n```ruby\nSmtpMock::TestFramework::RSpec::Interface.start_server  # creates and runs SmtpMock server instance\nSmtpMock::TestFramework::RSpec::Interface.stop_server!  # stops and clears current SmtpMock server instance\nSmtpMock::TestFramework::RSpec::Interface.clear_server! # clears current SmtpMock server instance\n```\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at \u003chttps://github.com/mocktools/ruby-smtp-mock\u003e. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct. Please check the [open tickets](https://github.com/mocktools/ruby-smtp-mock/issues). Be sure to follow Contributor Code of Conduct below and our [Contributing Guidelines](CONTRIBUTING.md).\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n\n## Code of Conduct\n\nEveryone interacting in the SmtpMock project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](CODE_OF_CONDUCT.md).\n\n## Credits\n\n- [The Contributors](https://github.com/mocktools/ruby-smtp-mock/graphs/contributors) for code and awesome suggestions\n- [The Stargazers](https://github.com/mocktools/ruby-smtp-mock/stargazers) for showing their support\n\n## Versioning\n\nSmtpMock uses [Semantic Versioning 2.0.0](https://semver.org)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmocktools%2Fruby-smtp-mock","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmocktools%2Fruby-smtp-mock","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmocktools%2Fruby-smtp-mock/lists"}