{"id":19063239,"url":"https://github.com/delner/rspec-hollerback-mocks","last_synced_at":"2026-06-14T23:32:30.930Z","repository":{"id":56892899,"uuid":"56740389","full_name":"delner/rspec-hollerback-mocks","owner":"delner","description":"RSpec mocks for the Hollerback gem.","archived":false,"fork":false,"pushed_at":"2016-05-21T18:34:35.000Z","size":11,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-03-03T04:29:48.766Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/delner.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-04-21T03:42:45.000Z","updated_at":"2017-06-29T13:32:01.000Z","dependencies_parsed_at":"2022-08-21T01:50:13.658Z","dependency_job_id":null,"html_url":"https://github.com/delner/rspec-hollerback-mocks","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/delner/rspec-hollerback-mocks","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/delner%2Frspec-hollerback-mocks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/delner%2Frspec-hollerback-mocks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/delner%2Frspec-hollerback-mocks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/delner%2Frspec-hollerback-mocks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/delner","download_url":"https://codeload.github.com/delner/rspec-hollerback-mocks/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/delner%2Frspec-hollerback-mocks/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34342089,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-14T02:00:07.365Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2024-11-09T00:29:21.798Z","updated_at":"2026-06-14T23:32:29.992Z","avatar_url":"https://github.com/delner.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"RSpec Hollerback Mocks\n==========\n\n[![Build Status](https://travis-ci.org/delner/rspec-hollerback-mocks.svg?branch=master)](https://travis-ci.org/delner/rspec-hollerback-mocks) ![Gem Version](https://img.shields.io/gem/v/rspec-hollerback-mocks.svg?maxAge=2592000)\n###### *For Ruby 2+, RSpec 3+*\n\n### Introduction\n\nAdds mocking extensions to RSpec for testing code that implements Hollerback.\n\n### Installation\n\n##### If you're not using Bundler...\n\nInstall the gem via:\n\n```\ngem install rspec-hollerback-mocks\n```\n\nThen require it in your `spec_helper.rb` with:\n\n```\nrequire 'rspec/hollerback/mocks'\n```\n\n##### If you're using Bundler...\n\nAdd the gem to your Gemfile:\n\n```\ngem 'rspec-hollerback-mocks'\n```\n\nThen `bundle install` to install the gem and its dependencies.\n\nFinally require it in your `spec_helper.rb` with:\n\n```\nrequire 'rspec/hollerback/mocks'\n```\n\n### Usage\n\n##### Triggering a callback using and_callback\n\nGiven a class that implements Hollerback, e.g:\n\n```ruby\nclass NoteApi\n  include Hollerback\n\n  # Callback-enabled function\n  def get_note(\u0026block)\n    # ...\n  end\nend\n```\n\nYou can mock callbacks on the class, or objects of the class using the `and_callback` condition.\n\n```ruby\ncontext \"for a class\" do\n  subject do\n    NoteApi.get_note do |on|\n      on.success { \"Success!\" }\n    end\n  end\n  it do\n    expect(NoteApi).to receive(:get_note).and_callback(:success)\n    expect(subject).to eq(\"Success!\")\n  end\nend\n\ncontext \"for an object\" do\n  let(:client) { NoteApi.new }\n  subject do\n    client.get_note do |on|\n      on.success { \"Success!\" }\n    end\n  end\n  it do\n    expect(client).to receive(:get_note).and_callback(:success)\n    expect(subject).to eq(\"Success!\")\n  end\nend\n```\n\nThe mocked function will return the output of the callback block you invoke.\n\n##### Chaining callbacks\n\nYou can also chain multiple callbacks, in which case the last callback will be the return value.\n\n```ruby\ncontext \"for an object that invokes multiple callbacks\" do\n  let(:client) { NoteApi.new }\n  subject do\n    client.get_note do |on|\n      on.created { \"Created new note!\" }\n      on.success { \"Success!\" }\n    end\n  end\n  it do\n    expect(client).to receive(:get_note).and_callback(:created).and_callback(:success)\n    expect(subject).to eq(\"Success!\")\n  end\nend\n```\n\n##### Returning a value after callbacks\n\nIf you want the mocked function to return a different value, then you can add RSpec's `and_return` to the end of the call.\n\n```ruby\ncontext \"for an object that invokes a callback and returns a value\" do\n  let(:note) { Note.new }\n  let(:client) { NoteApi.new }\n  subject do\n    client.get_note do |on|\n      on.success { \"Success!\" }\n    end\n  end\n  it do\n    expect(client).to receive(:get_note).and_callback(:success).and_return(note)\n    expect(subject).to eq(note)\n  end\nend\n```\n\n##### Mocking a class that uses a callback\n\nThis feature is most useful when you want to mock behavior on a class that consumes the callback-enabled class.\n\nFor example, let's say there is a `NoteApi#get_note` function that makes HTTP requests and triggers callbacks. Let's also say we wanted to use this `NoteApi` to power a feature that adds signatures to our notes.\n\n```ruby\nclass Autopen\n  def self.get_signed_note(note_id, signature)\n    note = NoteApi.get_note note_id do |on|\n      # If the note exists, add a signature to it and return it\n      on.found { |note| note.tap { |n| n.append(signature) } }\n\n      # Otherwise just return a new note without a signature\n      on.not_found { |note_id| Note.new(note_id) }\n    end\n  end\nend\n```\n\nIf we are writing specs for `Autopen` to test the `get_signed_note` method, we aren't interested in testing `NoteApi`. More importantly, we might not want that `NoteApi` class making actual HTTP calls that might make our test suite brittle, or otherwise slow it down.\n\nThis is where a mock is appropriate and the `and_callback` condition is most useful. Using it, we can implement a test that allows us to make the `NoteApi` trigger any callbacks we need to test the code we care about inside `get_signed_note`.\n\n```ruby\ndescribe Autopen do\n  describe \"#get_signed_note\" do\n    subject { Autopen.get_signed_note(note_id, signature) }\n    let(:note_id) { \"TPS Report\" }\n    let(:signature) { \"Peter Gibbons\\nSoftware Engineer\\nInitech\" }\n\n    context \"for a note that exists\" do\n      let(:note) { Note.new(\"Yes, I already got the memo.\") }\n      before(:each) { expect_any_instance_of(NoteApi).to receive(:get_signed_note).with(note_id).and_callback(:found, note) }\n      it { is_expected.to eq(note) }\n      it { expect(subject.body).to end_with(signature) }\n    end\n    context \"when given a note that does not exist\" do\n      before(:each) { expect_any_instance_of(NoteApi).to receive(:get_signed_note).with(note_id).and_callback(:not_found, note_id) }\n      it { expect(subject.body).to_not end_with(signature) }\n    end\n  end\nend\n```\n\n## Development\n\nInstall dependencies using `bundle install`. Run tests using `bundle exec rspec`\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/delner/rspec-hollerback-mocks.\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdelner%2Frspec-hollerback-mocks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdelner%2Frspec-hollerback-mocks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdelner%2Frspec-hollerback-mocks/lists"}