Project

mini_mock

0.0
No release in over a year
Record and replay requests using Typhoeus built-in stubbing functionality.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies

Runtime

 Project Readme

Gem Version

MiniMock

A Ruby Gem to record and replay requests using Typhoeus’ built-in stubbing functionality.

Installation

Add gem "mini_mock" to your Gemfile or install it yourself with gem install mini_mock.

Usage

#Start recording all Tyhpoeus requests
MiniMock.record
#Get a quote from GitHub's zen api
response = Typhoeus.get 'https://api.github.com/zen'
puts response.body
# => Avoid administrative distraction.

#Load saved mocks and block all outgoing requests
MiniMock.replay
#No new request is made
response = Typhoeus.get 'https://api.github.com/zen'
puts response.body
# => Avoid administrative distraction.

MiniMock saves responses in a ruby file with calls to Typhoeus.stub so that they can be easly edited to test how your code handles unexpected responses, errors, timeouts and all kinds of trickery the developers of the api you are consuming might have left for you to deal with.

Here is the file generated by the example above:

# mini_mock/mocks.rb
response = Typhoeus::Response.new(
  code: 200,
  status_message: "",
  body: "Avoid administrative distraction.",
  headers: {"server"=>"GitHub.com", "date"=>"Mon, 13 Mar 2023 23:20:38 GMT", "content-type"=>"text/plain;charset=utf-8", "x-github-api-version-selected"=>"2022-11-28", "access-control-expose-headers"=>"ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset", "access-control-allow-origin"=>"*", "strict-transport-security"=>"max-age=31536000; includeSubdomains; preload", "x-frame-options"=>"deny", "x-content-type-options"=>"nosniff", "x-xss-protection"=>"0", "referrer-policy"=>"origin-when-cross-origin, strict-origin-when-cross-origin", "content-security-policy"=>"default-src 'none'", "vary"=>"Accept-Encoding, Accept, X-Requested-With", "x-ratelimit-limit"=>"60", "x-ratelimit-remaining"=>"40", "x-ratelimit-reset"=>"1678753155", "x-ratelimit-resource"=>"core", "x-ratelimit-used"=>"20", "accept-ranges"=>"bytes", "content-length"=>"33", "x-github-request-id"=>"C559:5344:3E4851:477975:640FAFC6"},
  effective_url: "https://api.github.com/zen",
  options: {:httpauth_avail=>0, :total_time=>0.240721, :starttransfer_time=>0.239971, :appconnect_time=>0.078561, :pretransfer_time=>0.078669, :connect_time=>0.042008, :namelookup_time=>0.017529, :redirect_time=>0.0, :effective_url=>"https://api.github.com/zen", :primary_ip=>"20.201.28.148", :response_code=>200, :request_size=>115, :redirect_count=>0, :redirect_url=>nil, :size_upload=>0.0, :size_download=>33.0, :speed_upload=>0.0, :speed_download=>137.0, :return_code=>:ok, :response_headers=>"HTTP/2 200 \r\nserver: GitHub.com\r\ndate: Mon, 13 Mar 2023 23:20:38 GMT\r\ncontent-type: text/plain;charset=utf-8\r\nx-github-api-version-selected: 2022-11-28\r\naccess-control-expose-headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset\r\naccess-control-allow-origin: *\r\nstrict-transport-security: max-age=31536000; includeSubdomains; preload\r\nx-frame-options: deny\r\nx-content-type-options: nosniff\r\nx-xss-protection: 0\r\nreferrer-policy: origin-when-cross-origin, strict-origin-when-cross-origin\r\ncontent-security-policy: default-src 'none'\r\nvary: Accept-Encoding, Accept, X-Requested-With\r\nx-ratelimit-limit: 60\r\nx-ratelimit-remaining: 40\r\nx-ratelimit-reset: 1678753155\r\nx-ratelimit-resource: core\r\nx-ratelimit-used: 20\r\naccept-ranges: bytes\r\ncontent-length: 33\r\nx-github-request-id: C559:5344:3E4851:477975:640FAFC6\r\n\r\n", :response_body=>"Avoid administrative distraction.", :debug_info=>""}
)
Typhoeus.stub("https://api.github.com/zen", {:method=>:get})
.and_return(response)

The line lengths are not great, but that's a tradeoff to make the mocks file easier to navigate while keeping complete responses and requests in the same file. Speaking of messy mocks files, mocks.rb is just the default file name. To organize your mocks in multiple files, pass a parameter to .record as in MiniMock.record('open-ai-api') and subsequent responses will be saved to open-ai-api.rb in the mini_mock folder. To latter load these responses, call MiniMock.replay('open-ai-api').

This is also useful in tests:

Run this test once as

test "make some requests" do
    MiniMock.record 'reqs_test'
    # your job/hydra run
    # test assertions
  end

And then forever, deterministically, as

test "make some requests" do
    MiniMock.replay 'reqs_test'
    # your job/hydra run
    # test assertions
  end

To turn off MiniMock and allow real network connections again, use the .off method:

MiniMock.off

This will also clear any currenly loaded mocks.

Weirdness

Saving requests to ruby files from within a heredoc is, to say the least, uncoventional. While this gem is desinged to be fun to use in development/testing, it's implementation probalby has issues with more complex requests. Writting stuff from the internet to a file that will be latter executed as Ruby also may need more security consideration than just calling inspect on the response values. That's all probalby fine if you are having fun and working with somewhat trusted data. Otherwise, checkout more advanced and safer mocking gems like WebMock and VCR.

Considerations

  • MiniMock only supports Typhoeus as the HTTP library, while other gems support multiple HTTP libraries such as Net::HTTP, RestClient, Faraday, etc.
  • MiniMock only records requests and responses as they are, without allowing any automatic filtering of sensitive data such as passwords or API keys.
  • MiniMock does not provide any way to verify that the expected requests have been made, or to set expectations on the number or order of requests.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/felipedmesquita/mini_mock.