Skip to content

Commit

Permalink
Add clear mock option (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
parroty committed Sep 21, 2014
1 parent b577bdf commit f7e2058
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 16 deletions.
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,24 @@ test "filter url param flag removes url params when recording cassettes" do
refute String.contains?(json, "should_not_be_contained")
```

#### Clearing Mock After Each Cassette
By default, mocking through `:meck.expect` is not cleared after each `use_cassette`. It can cause error when mixing actual/mocking accesses. In order to clear mock, please specify `[clear_mock: :true]` option through either of the followings.

```elixir
# For applying all the tests under the module.
defmodule ExVCR.Adapter.OptionsTest do
use ExVCR.Mock, options: [clear_mock: true]
use ExUnit.Case, async: false
...
```

```elixir
# For applying specific test.
use_cassette "option_clean_each", clear_mock: true do
assert HTTPotion.get(@url, []).body == "test_response1"
end
```

### Mix Tasks
The following tasks are added by including exvcr package.
- [mix vcr](#mix-vcr-show-cassettes)
Expand Down
4 changes: 2 additions & 2 deletions lib/exvcr/iex.ex
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ defmodule ExVCR.IEx do
recorder = Recorder.start(
unquote(options) ++ [fixture: "", adapter: unquote(adapter)])

target_methods = adapter.target_methods(recorder)
module_name = adapter.module_name
target_methods = adapter_method.target_methods(recorder)
module_name = adapter_method.module_name

Enum.each(target_methods, fn({function, callback}) ->
:meck.expect(module_name, function, callback)
Expand Down
29 changes: 15 additions & 14 deletions lib/exvcr/mock.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,19 @@ defmodule ExVCR.Mock do

defmacro __using__(opts) do
adapter = opts[:adapter] || ExVCR.Adapter.IBrowse
options = opts[:options]

quote do
import ExVCR.Mock
:application.start(unquote(adapter).module_name)
use unquote(adapter)

def adapter do
def adapter_method do
unquote(adapter)
end

def setup_all do
:meck.new(adapter.module_name, [:passthrough])
:ok
end

def teardown_all do
:meck.unload(adapter.module_name)
:ok
def options_method do
unquote(options)
end
end
end
Expand All @@ -35,13 +30,16 @@ defmodule ExVCR.Mock do
defmacro use_cassette(:stub, options, test) do
quote do
stub_fixture = "stub_fixture_#{ExVCR.Util.uniq_id}"
stub = prepare_stub_record(unquote(options), adapter)
recorder = Recorder.start([fixture: stub_fixture, stub: stub, adapter: adapter])
stub = prepare_stub_record(unquote(options), adapter_method)
recorder = Recorder.start([fixture: stub_fixture, stub: stub, adapter: adapter_method])

mock_methods(recorder, adapter)
mock_methods(recorder, adapter_method)

try do
unquote(test)
if options_method[:clear_mock] || unquote(options)[:clear_mock] do
:meck.unload(adapter_method.module_name)
end
end
end
end
Expand All @@ -52,12 +50,15 @@ defmodule ExVCR.Mock do
defmacro use_cassette(fixture, options, test) do
quote do
recorder = Recorder.start(
unquote(options) ++ [fixture: normalize_fixture(unquote(fixture)), adapter: adapter])
unquote(options) ++ [fixture: normalize_fixture(unquote(fixture)), adapter: adapter_method])

mock_methods(recorder, adapter)
mock_methods(recorder, adapter_method)

try do
unquote(test)
if options_method[:clear_mock] || unquote(options)[:clear_mock] do
:meck.unload(adapter_method.module_name)
end
after
Recorder.save(recorder)
end
Expand Down
65 changes: 65 additions & 0 deletions test/options_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
defmodule ExVCR.Adapter.OptionsTest do
defmodule All do
use ExVCR.Mock, options: [clear_mock: true]
use ExUnit.Case, async: false

@port 34003
@url "http://localhost:#{@port}/server"

setup_all do
HTTPotion.start
:ok
end

test "clearn option works" do
HttpServer.start(path: "/server", port: @port, response: "test_response1")
use_cassette "option_clean_all" do
assert HTTPotion.get(@url, []).body == "test_response1"
end
HttpServer.stop(@port)

# this method should not be mocked
HttpServer.start(path: "/server", port: @port, response: "test_response2")
assert HTTPotion.get(@url, []).body == "test_response2"
HttpServer.stop(@port)

# this method should be mocked
use_cassette "option_clean_all" do
assert HTTPotion.get(@url, []).body == "test_response1"
end
end
end

defmodule Each do
use ExVCR.Mock
use ExUnit.Case, async: false

@port 34004
@url "http://localhost:#{@port}/server"

setup_all do
HTTPotion.start
:ok
end

test "clean_each switch works" do
HttpServer.start(path: "/server", port: @port, response: "test_response1")
use_cassette "option_clean_each", clear_mock: true do
assert HTTPotion.get(@url, []).body == "test_response1"
end
HttpServer.stop(@port)

# this method should not be mocked
HttpServer.start(path: "/server", port: @port, response: "test_response2")
assert HTTPotion.get(@url, []).body == "test_response2"
HttpServer.stop(@port)

# this method should be mocked
use_cassette "option_clean_each" do
assert HTTPotion.get(@url, []).body == "test_response1"
end
end
end

end

0 comments on commit f7e2058

Please sign in to comment.