stripe-ruby-mock: testing Stripe code without touching the network
A mocking library for testing stripe ruby
At a glance
- What is it?
- stripe-ruby-mock overrides the request method of stripe-ruby so that calls return test data instead of reaching Stripe, and it adds helpers for card errors, plans and card tokens. It follows Stripe's own API version rather than semantic versioning, it does not implement every endpoint, and its most recent release tag is v4.0.0 from 2024-08-06.
- Who is it for?
- stripe-ruby-mock is a good fit for a Ruby service that has to prove it handles declined cards and unusual API responses, because it stubs the HTTP layer rather than the client, so your production code path stays intact. It is the wrong tool if your tests depend on an endpoint the library has not implemented, since the coverage warning is explicit, and its versioning scheme will not look familiar to anyone who assumes semantic versioning.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 44 days ago.
- What is it written in?
- Mainly Ruby, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The request method is what gets overridden
The mechanism is one sentence long, and the whole library follows from it: at its core, this library overrides the request method of stripe-ruby to skip all http calls and instead directly return test data.
That is a different design from stubbing your own service layer. Your application code calls Stripe::Customer.create, the stripe-ruby client builds a real request object, and the interception happens at the last moment before the socket is opened. The result is that tests exercise the same client code, the same parameter handling and the same error classes that production uses, with no server involved.
The test data is organised per endpoint, and the library ships a set of strategies for the calls that need several parameters, which is what the test helpers are built on. Anything not covered by a strategy is handled by returning test data directly, and for everything else the guidance is simply to use Stripe as you normally would, as if StripeMock were not there.
One limitation is stated without hedging: the library does not cover all Stripe API endpoints, and a missing endpoint means either an issue or a contribution following a documented wiki page for implementing a new behaviour.
The version number tracks Stripe's API, not your app
The versioning system here is unusual enough to state precisely, because it will confuse anyone coming from a normal gem. The major number is for breaking changes involving how you use StripeMock itself. The minor number is for breaking changes involving Stripe's API. The patch number covers non-breaking changes and fixes involving Stripe's API, and non-breaking changes or features of StripeMock itself.
So a minor bump can break your code even though nothing about StripeMock's interface changed, because Stripe changed underneath it. The reasoning given is that StripeMock tries to keep up with Stripe's API version.
The version being targeted is stated as 2024-06-20 on master, with the honest qualification that some features are not implemented yet. The supported range of the stripe gem is greater than 5 and up to 13. Older API branches are kept as separate branches, with api-2015-09-08 tied to gem version 2.4.1 and api-2014-06-17 available as its own tree.
The version 5.0.0 notes say the same support range applies after the breaking changes, and version 3.0.0 covered an earlier range of stripe greater than 5 and less than 6. Reading the changelog and the breaking change notes before upgrading is not optional here.
Test helpers remove the boilerplate calls
Some Stripe API calls need several parameters before they do anything useful, and the helper exists to keep the test brief. You create a helper once, then call the specific strategy you need.
describe MyApp do
let(:stripe_helper) { StripeMock.create_test_helper }
it "creates a stripe plan" do
plan = stripe_helper.create_plan(:id => 'my_plan', :amount => 1500)
# The above line replaces the following:
# plan = Stripe::Plan.create(
# :id => 'my_plan',
# :name => 'StripeMock Default Plan ID',
# :amount => 1500,
# :currency => 'usd',
# :interval => 'month'
# )
expect(plan.id).to eq('my_plan')
expect(plan.amount).to eq(1500)
end
endThe available helpers are the plan creator, a plan deleter and a card token generator, and they live under lib/stripe_mock/test_strategies/.
stripe_helper.create_plan(my_plan_params)
stripe_helper.delete_plan(my_plan_params)
stripe_helper.generate_card_token(my_card_params)The card token helper is the one that shows up most, because a customer create call with a source needs a token. The documentation notes that you can specify :source in place of :card, with the same value, to get a customer back with source data attached.
prepare_card_error makes error paths assertable
Testing a declined card usually means typing out fake card numbers and hoping the gateway returns the error you expect. The library takes that work away by letting you declare the error you want before the call, so the test asserts on a real Stripe error class with a real status code and error code.
it "mocks a declined card error" do
# Prepares an error for the next create charge request
StripeMock.prepare_card_error(:card_declined)
expect { Stripe::Charge.create(amount: 1, currency: 'usd') }.to raise_error {|e|
expect(e).to be_a Stripe::CardError
expect(e.http_status).to eq(402)
expect(e.code).to eq('card_declined')
}
endThe point is that the error object is a Stripe::CardError, not a stub of one, so the same rescue and retry logic your production code has is exercised. A list of built-in errors is available, covering incorrect_number, invalid_number, invalid_expiry_month, invalid_expiry_year, invalid_cvc, expired_card, incorrect_cvc, card_declined, missing, processing_error and incorrect_zip, with the details of each defined in lib/stripe_mock/api/errors.rb.
There is one ordering requirement that is easy to miss, and the documentation states it twice: StripeMock has to be started in a before filter with StripeMock.start, or the prepared error is not in place when the request arrives.
toggle_live runs the same suite against Stripe's test servers
A mock that never talks to the real API has a failure mode of its own: the mock can be wrong. The library addresses that with a switch that runs your test suite, or a subset of it, against Stripe's live test servers.
The switch is StripeMock.toggle_live(true), and it is meant to be called from the RSpec configuration block, where the presence of a :live tag in the filter manager decides whether live mode is turned on. The two RSpec generations differ in one detail, since RSpec 3.x checks c.filter_manager.inclusions.rules while the 2.x form checks c.filter_manager.inclusions.keys.
With that configuration in place, the live subset is selected with a command line tag.
rspec -t liveThis is the mechanism that turns the library from a convenience into a safety net. The same assertions run in both modes, so a mock that drifts from the real API shows up as a failing live run rather than as a bug that escapes into production. The library can be used with any Ruby testing library, not only RSpec.
Endpoint coverage is the gap, and the maintainer is one person
Two limits are worth knowing before you commit to it. The first is coverage, and it is a direct consequence of a project that tracks a moving API: the library does not cover all Stripe API endpoints, and if you need one that is missing you are asked to open an issue or follow the guide for implementing a new behaviour.
The second is maintenance. The project asks for more core contributors, and the reason given is that the gem has unexpectedly grown in popularity and the maintainer has gotten busy. The bar for joining is explicit and unusual: submit a significant enough pull request, have it merged into master, and then you are added as a collaborator.
The repository layout supports the usual Ruby practice rather than anything exotic. There is a gemspec, a Gemfile, a Rakefile, an Appraisals file and a gemfiles/ directory for testing against multiple dependency sets, along with lib/ and spec/ directories and a .env file. The test workflow is driven by RSpec, with a badge pointing at a rspec_tests.yml workflow. The last push to the repository was on 2026-09-09, and the most recent release tag is v4.0.0 from 2024-08-06, with release candidates for 3.1.0 dated 2021.
Editorial conclusion
stripe-ruby-mock is a good fit for a Ruby service that has to prove it handles declined cards and unusual API responses, because it stubs the HTTP layer rather than the client, so your production code path stays intact. It is the wrong tool if your tests depend on an endpoint the library has not implemented, since the coverage warning is explicit, and its versioning scheme will not look familiar to anyone who assumes semantic versioning. Before adopting it, list the endpoints your suite actually touches against the library, pin the gem version, and note that the newest published tag is v4.0.0 while the master branch already targets the 2024-06-20 Stripe API version.
Frequently asked questions
How do I install stripe-ruby-mock?
Add gem 'stripe-ruby-mock' to your Gemfile. The stated requirements are Ruby 3.0.0 or later and the stripe gem at a version greater than 5 and up to 13.
How does stripe-ruby-mock work without a Stripe server?
It overrides the request method of stripe-ruby so that all http calls are skipped and test data is returned directly. Your application still calls the real Stripe client, so the client code path stays the same.
How do I test a declined card with stripe-ruby-mock?
Call StripeMock.prepare_card_error(:card_declined) before the request, with StripeMock.start already run in a before filter, and then assert that the call raises a Stripe::CardError with http_status 402 and code card_declined. Other built-in errors include incorrect_number, expired_card, processing_error and missing.
Can stripe-ruby-mock run tests against Stripe's real test servers?
Yes. StripeMock.toggle_live(true) switches the suite over, and with the RSpec configuration shown in the documentation the live subset is run with rspec -t live. The same assertions then run against Stripe's live test servers.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/stripe-ruby-mock-stripe-ruby-mock)Was this useful?