{"id":22946611,"url":"https://github.com/mmower/passport_control","last_synced_at":"2025-04-01T22:40:26.841Z","repository":{"id":594974,"uuid":"229965","full_name":"mmower/passport_control","owner":"mmower","description":"Create mocks \u0026 stubs on ActiveRecord instances by \u003cid\u003e ","archived":false,"fork":false,"pushed_at":"2009-06-17T23:20:09.000Z","size":84,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-07T14:45:40.484Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mmower.png","metadata":{"files":{"readme":"README.markdown","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2009-06-17T21:25:32.000Z","updated_at":"2019-08-13T14:26:32.000Z","dependencies_parsed_at":"2022-07-18T22:59:27.404Z","dependency_job_id":null,"html_url":"https://github.com/mmower/passport_control","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mmower%2Fpassport_control","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mmower%2Fpassport_control/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mmower%2Fpassport_control/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mmower%2Fpassport_control/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mmower","download_url":"https://codeload.github.com/mmower/passport_control/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246724609,"owners_count":20823542,"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":[],"created_at":"2024-12-14T14:47:27.829Z","updated_at":"2025-04-01T22:40:26.819Z","avatar_url":"https://github.com/mmower.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"Passport Control\n================\n\nPassport Control is a Rails plugin that augments ActiveRecord model classes with **per-record** callbacks. The intended purpose is to allow mocking \u0026 stubbing  in tests on a per-record, rather than per-instance, basis.\n\nHere is a typical example of mocking a method in a test setup: (*)\n\n    setup do\n      @user = User.make\n      @content = @user.contents.make\n      mock( @content ).foo { \"foo!\" }\n    end\n\nSetting up a mock in this way works fine in a context where you can pass your mocked `@content` instance directly into your test (e.g. a unit test). But this becomes more complicated when your test is not responsible for directly providing the object you need to mock.\n\nFor example controller methods usually take the id of a record and look up an instance using `find` and friends. Calls to `find` returns the same record but a different instance to the one your mock method is installed on.\n\nTypical work arounds to this problem involve either `any_instance` (if it's available to you), or stubbing your model class to ensure your pre-mocked instance is returned by `find`. This can get messy, especially where associations are involved.\n\nMaybe you've wished you could simply tell Rails \"Look, just mock method #foo of record 13 wherever it comes from\"? That's where Passport Control comes in.\n\nHere's an example:\n\n    setup do\n      @user = User.make\n      @content = @user.contents.make\n      @content.at_passport_control { |content| mock( content ).foo { \"foo!\" }\n      get :show, :id =\u003e @content.id\n    end\n\nCalling `at_passport_control` on the instance ensures that the block is called when the record corresponding to `@content` gets instantiated by ActiveRecord, no matter what chain of methods is involved. This example ensures that when the controller method `#show` looks up the record given it's id that the returned instance correctly mocks the method `#foo`.\n\nTest Framework Integration\n--------------------------\n\nTo ensure that passport control mocks \u0026 stubs don't leak from one test to another install the PassportControl adapater. An adapter is provided for Test::Unit based systems, add the following to your `test_helper.rb`\n\n    require 'passport_control'\n    \n    class Test::Unit::TestCase\n      include PassportControl::Adapters::TestUnit\n    end\n\nA similar adapter should be easy enough to write for other frameworks.\n\nThe Low Down\n------------\n\nPassport Control is specifically intended for use in writing tests **not** for use in production code.\n\nIt works by replacing the `instantiate` method of ActiveRecord::Base with an augmented version that manages the per-class/per-id callback lists. Initial results suggest that this doesn't add a significant overhead during test runs but, given how often `instantiate` is going to get called during the lifetime of a real application, you don't want it in production.\n\nAlso monkeypatching such a fundamental ActiveRecord method is surely evil and angry villagers with torches and pitchforks will be involved somehow. You have been warned!\n\nNotes\n-----\n\n* I use [Shoulda](http://github.com/thoughtbot/shoulda/tree/master), [RR](http://github.com/btakita/rr/tree/master), and [Machinist](http://github.com/notahat/machinist/tree/master) for testing.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmmower%2Fpassport_control","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmmower%2Fpassport_control","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmmower%2Fpassport_control/lists"}