blog
Read Email in Ruby and Rails Tests with MailSlurp
Create a private test inbox, receive email in Ruby, and extract verification codes for Rails, RSpec, and integration tests with the MailSlurp Ruby SDK.

To read email in a Ruby or Rails test, create a private inbox with the MailSlurp Ruby SDK, use its address in your application, then wait for the message with WaitForControllerApi. The returned email object contains the subject, sender, recipients, body, headers, and attachment metadata that your test can inspect.
This approach lets an RSpec, Minitest, or browser test exercise the real customer workflow. It works well for sign-up verification, password resets, magic links, receipts, and one-time passcodes.
Ruby email test flow
A reliable end-to-end email test has five steps:
- Create a new inbox for the test run.
- Submit that inbox address to your Rails application.
- Wait for the expected email with a finite timeout.
- Assert the message content and extract its link or code.
- Use the link or code, then assert the resulting application state.
Using one inbox per test prevents a message from another test or an earlier run from satisfying the wrong assertion.
Install the MailSlurp Ruby SDK
Add the MailSlurp client and its HTTP dependency to your Gemfile, then run bundle install.
source "https://rubygems.org"
gem 'mailslurp_client'
gem 'typhoeus'
Create an API key in your MailSlurp account and provide it to the test process as an environment variable. Keep the key in your CI secret store rather than committing it to the repository.
require 'mailslurp_client'
MailSlurpClient.configure do |config|
config.api_key['x-api-key'] = ENV['API_KEY']
end
For example, run a test locally with:
API_KEY=your-api-key bundle exec ruby test/user_signup_test.rb
Create a test email address in Ruby
Create an inbox controller once for the test, then create an inbox. Each inbox has an id for API calls and an email_address that can be passed to the application under test.
inbox_controller = MailSlurpClient::InboxControllerApi.new
options = {
name: "My test inbox",
inboxType: "SMTP_INBOX"
}
inbox = inbox_controller.create_inbox_with_options(options)
assert_match /@mailslurp/, inbox.email_address
Use inbox.email_address in the real Rails sign-up, password-reset, or notification action. That can be an integration-test request, a system test driven by Capybara, or a call to an application service.
Receive the email in Ruby
After the application sends the message, wait for the newest unread email in the inbox. A wait call is more reliable than adding a fixed sleep because it returns as soon as the message arrives and fails with a clear timeout when delivery does not happen.
wait_for_controller = MailSlurpClient::WaitForControllerApi.new
wait_options = {
inbox_id: inbox.id,
timeout: 120000,
unread_only: true
}
email = wait_for_controller.wait_for_latest_email(wait_options)
assert_match /Welcome/, email.body
The example waits for up to 120 seconds and asserts that the email body contains the expected welcome text. In a production test suite, also check the sender, subject, recipient, and the specific content that the customer needs.
If several emails can reach the same inbox, use the wait-for-email API to match the expected message instead of assuming the latest email is the right one.
Extract a verification code
You can extract a one-time code from the received body with a regular expression, then submit that value to the application and assert that the account is verified.
code = email.body.match(/Your code is: ([0-9]{6})/)[1]
assert_equal code, '123456'
Match the wording and code format used by your own template. For a magic-link flow, extract the link instead and navigate to it with the same browser session that started the sign-up or reset.
Use the inbox in a Rails integration test
The MailSlurp calls fit around the application behavior rather than replacing it. A Rails integration test can create the inbox, post the address to the real route, receive the resulting message, and complete verification:
class UserSignupTest < ActionDispatch::IntegrationTest
test "a user can verify their account by email" do
inbox_controller = MailSlurpClient::InboxControllerApi.new
inbox = inbox_controller.create_inbox_with_options(
name: "Rails sign-up test",
inboxType: "SMTP_INBOX"
)
post "/sign-up", params: { email: inbox.email_address }
assert_response :success
email = MailSlurpClient::WaitForControllerApi.new.wait_for_latest_email(
inbox_id: inbox.id,
timeout: 120_000,
unread_only: true
)
code = email.body.match(/Your code is: ([0-9]{6})/)[1]
post "/verify", params: { email: inbox.email_address, code: code }
assert_response :success
end
end
Adapt the routes, response checks, and code pattern to your application. The important part is that the test completes the action triggered by the email. Checking only that a message exists does not prove that its link or code works.
Make Ruby email tests dependable
- Create isolated inboxes. Use a fresh inbox for each test, worker, or scenario that can run concurrently.
- Wait with a timeout. Avoid fixed sleeps and unbounded polling. Choose a timeout that reflects the slowest expected test environment.
- Match the intended message. Assert the sender, recipient, subject, or body before extracting values.
- Fail clearly. Include the inbox ID and expected subject in test diagnostics without logging the API key or sensitive message content.
- Complete the customer action. Follow the link or submit the code, then assert the verified, authenticated, or recovered state.
For a full browser-driven example, see testing authentication with Capybara, Cucumber, and Selenium. You can also review the Ruby SDK documentation and the broader guide to receiving email in code.