Skip to content

Commit

Permalink
Add functionality to call the original function
Browse files Browse the repository at this point in the history
  • Loading branch information
brain-geek authored and edgurgel committed Jul 18, 2024
1 parent 0be0492 commit fb942a8
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 3 deletions.
16 changes: 14 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ Calculator
verify!()
```

Using `expect/4` on intra-module functions will not work, unless the function is referenced by it's fully qualified name.
Using `expect/4` on intra-module functions will not work, unless the function is referenced by it's fully qualified name.

```elixir
defmodule Calculator do
Expand Down Expand Up @@ -206,7 +206,7 @@ To use DSL Mode `use Mimic.DSL` rather than `use Mimic` in your test. DSL Mode
```

## Stubs with fake module
`stub_with/2` enable substitute function call of a module with another similar module
`stub_with/2` enable substitute function call of a module with another similar module.

```elixir
defmodule BadCalculator do
Expand All @@ -222,6 +222,18 @@ To use DSL Mode `use Mimic.DSL` rather than `use Mimic` in your test. DSL Mode
end
```

## Calling the original
`call_original/3` allows to call original unmocked version of the function.

```elixir
setup :set_mimic_private

test "calls original function even if it has been is stubbed" do
stub_with(Calculator, InverseCalculator)

assert call_original(Calculator, :add, [1, 2]) == 3
end
```

## Implementation Details & Performance

Expand Down
32 changes: 32 additions & 0 deletions lib/mimic.ex
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,38 @@ defmodule Mimic do
end
end

@doc """
Call original implementation of a function.
This function allows you to call the original implementation of a function,
even if it has been stubbed, rejected or expected.
## Arguments:
* `module` - the name of the module in which we're calling.
* `function_name` - the name of the function we're calling.
* `args` - the arguments of the function we're calling.
## Raises:
* If `function_name` does not exist in `module`.
## Example:
iex> Mimic.call_original(Calculator, :add, [1, 2])
3
"""
@spec call_original(module, atom, list) :: any
def call_original(module, function_name, args) do
arity = length(args)

raise_if_not_exported_function!(module, function_name, arity)
func = Function.capture(Mimic.Module.original(module), function_name, arity)

Kernel.apply(func, args)
end

@doc """
Verifies the current process after it exits.
Expand Down
40 changes: 39 additions & 1 deletion test/mimic_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -924,7 +924,7 @@ defmodule Mimic.Test do
end
end

describe "copy/1 with duplicates does nothing" do
describe "copy/1 with duplicates" do
setup :set_mimic_private

test "stubs still stub" do
Expand All @@ -946,6 +946,44 @@ defmodule Mimic.Test do
end
end

describe "call_original/3" do
setup :set_mimic_private

test "calls original function even if it has been is stubbed" do
stub_with(Calculator, InverseCalculator)

assert call_original(Calculator, :add, [1, 2]) == 3
end

test "calls original function even if it has been rejected as a module function" do
Mimic.reject(Calculator, :add, 2)

assert call_original(Calculator, :add, [1, 2]) == 3
end

test "calls original function even if it has been rejected as a capture" do
Mimic.reject(&Calculator.add/2)

assert call_original(Calculator, :add, [1, 2]) == 3
end

test "when called on a function that has not been stubbed" do
assert call_original(Calculator, :add, [1, 2]) == 3
end

test "when called on a module that does not exist" do
assert_raise ArgumentError, "Function add/2 not defined for NonExistentModule", fn ->
call_original(NonExistentModule, :add, [1, 2])
end
end

test "when called on a function that does not exist" do
assert_raise ArgumentError, "Function non_existent_call/2 not defined for Calculator", fn ->
call_original(Calculator, :non_existent_call, [1, 2])
end
end
end

describe "structs" do
setup :set_mimic_private

Expand Down

0 comments on commit fb942a8

Please sign in to comment.