{"id":18000481,"url":"https://github.com/nsomar/ex_stub","last_synced_at":"2025-12-12T00:20:40.400Z","repository":{"id":62429462,"uuid":"83245889","full_name":"nsomar/ex_stub","owner":"nsomar","description":"ExStub provides an easy way to stub a module and record the function calls on it.","archived":false,"fork":false,"pushed_at":"2017-04-02T19:45:28.000Z","size":20,"stargazers_count":8,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-21T11:50:24.060Z","etag":null,"topics":["elixir","mock","stub","stubbing","tdd","test","testing","unittest"],"latest_commit_sha":null,"homepage":"","language":"Elixir","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/nsomar.png","metadata":{"files":{"readme":"README.md","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":"2017-02-26T22:39:34.000Z","updated_at":"2023-07-29T23:43:38.000Z","dependencies_parsed_at":"2022-11-01T20:05:14.287Z","dependency_job_id":null,"html_url":"https://github.com/nsomar/ex_stub","commit_stats":null,"previous_names":["oarrabi/ex_stub"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nsomar%2Fex_stub","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nsomar%2Fex_stub/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nsomar%2Fex_stub/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nsomar%2Fex_stub/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nsomar","download_url":"https://codeload.github.com/nsomar/ex_stub/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245195962,"owners_count":20575938,"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":["elixir","mock","stub","stubbing","tdd","test","testing","unittest"],"created_at":"2024-10-29T23:12:17.419Z","updated_at":"2025-12-12T00:20:40.364Z","avatar_url":"https://github.com/nsomar.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ExStub\n[![Build Status](https://travis-ci.org/oarrabi/ex_stub.svg?branch=master)](https://travis-ci.org/oarrabi/ex_stub)\n[![Hex.pm](https://img.shields.io/hexpm/v/ex_stub.svg)](https://hex.pm/packages/ex_stub)\n[![API Docs](https://img.shields.io/badge/api-docs-yellow.svg?style=flat)](http://hexdocs.pm/ex_stub/)\n[![Coverage Status](https://coveralls.io/repos/github/oarrabi/ex_stub/badge.svg?branch=master)](https://coveralls.io/github/oarrabi/ex_stub?branch=master)\n[![Inline docs](http://inch-ci.org/github/oarrabi/ex_stub.svg?branch=master)](http://inch-ci.org/github/oarrabi/ex_stub)\n\n`ExStub` provides an easy way to stub a module and record the function calls on it.\n\n## Installation\n\nAdd `ex_stub` to your deps in `mix.exs` as a development dependency.\n\n```elixir\ndef deps do\n  [{:ex_stub, \"~\u003e 0.1.0\", only: :test}]\nend\n```\n\n## Usage\n\nIf you have a module in your original application like:\n\n```elixir\ndefmodule OriginalModule do\n  def process(param), do: :original_process\n  def another_method, do: :original_method\nend\n```\n\nYou can quickly create a stub copy of this module using `defstub`\n\n```elixir\nuse ExStub\n\ndefstub MyStub, for: OriginalModule do\n  def process(true), do: :stubbed1\n  def process(false), do: :stubbed2\n  def process(1), do: :stubbed3\nend\n```\n\nNow you can pass around `MyStub` instead of `OriginalModule`.\nWhen you invoke method from the created `MyStub`, if the method was stubbed it will call the stubbed version.\nElse the original version will be called.\n\n```elixir\nMyStub.process(true) # returns :stubbed1\nMyStub.process(false) # returns :stubbed2\nMyStub.process(1) # returns :stubbed3\n\nMyStub.process(20) # returns :original_process\n\nMyStub.another_method # returns :original_method\n```\n\nNotice that Since we did not stub `another_method`, calling it on `MyStub` returns the original implementation.\nAlso when calling `MyStub.process(20)` the original implementation is called since it failed pattern matching with our stub version of the method.\n\n----\n\nAs a safety procedure, if you try to stub a method that is not found in the original module. ExStub will throw a compilation error telling you about the unexpected stubbed method.\n\n```elixir\ndefstub MyStub, for: OriginalModule do\ndef new_method(), do: :stubbed1\nend\n```\n\nThe following error will be thrown\n\n```\n** (RuntimeError) Cannot provide implementations for methods that are not in the original module\nThe def `{:new_method, 0}` is not defined in module `OriginalModule`\n```\n\n## Recording method calls\nAll the functions called on the `defstub` created module will be recorded.\n\nTo get all the functions calls on `YourModule` module\n```elixir\nExStub.Recorder.calls(YourModule)\n```\n\nTo get all the `:the_method` function calls on `YourModule` \n```elixr\nExStub.Recorder.calls(YourModule, :the_method)\n```\n\nAlternativey, you can use `assert_called` in your unit tests:\n\nThe syntax is `assert_called ModuleName.function_name(params)`\n\n```elixir\n# No parameters\nassert_called ModuleName.function_name\n\n# nil passed\nassert_called ModuleName.function_name(nil)\n\n# multiple parameters\nassert_called ModuleName.function_name(1, 2)\n```\n\nSome more examples\n\n```elixir\nMyStub.process(1)\n\n# Passes since we called the function with [1]\nassert_called MyStub.process(1)\n\n# Fails since the parameters dont match\nassert_called MyStub.process(1, 2)\n\n# Fails since we did not call `another_method`\nassert_called MyStub.another_method\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnsomar%2Fex_stub","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnsomar%2Fex_stub","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnsomar%2Fex_stub/lists"}