parroty / exvcr

HTTP request/response recording library for elixir, inspired by VCR.
MIT License
722 stars 132 forks source link

Allow cache to be skipped when running a cassette #100

Open rrpff opened 7 years ago

rrpff commented 7 years ago

Adds a skip_cache option which can be passed to use_cassette, which will prevent cache from being for requests within the cassette, but will still record the responses for each. If the option is removed after recording, subsequent runs will use the correct responses.

We need this for cassettes which include more than one request to the same URL, which would be matched against the cache during the first recording, but should return different responses.

This fixes a problem we're having using the library, but appreciate it might not be the preferred fix. If you've got any suggestions on how to do this better, happy to hear them.

coveralls commented 7 years ago

Coverage Status

Coverage increased (+0.05%) to 93.034% when pulling 958625afa9ca1672cb9cb2fabb541239671c69b4 on zuren:add-skip-cache-option into d3722997ab223940f2e45b566ced9791895ac023 on parroty:master.

parroty commented 7 years ago

Thanks for the PR! I think it works as long it's optional setting, but I have a question.

When I try to delete skips_cache.json and then run tests, it fails with following error (and captured skips_cache.json only contains one response). How original one is recorded? (Is there any special procedure?)

$ exvcr git:(add-skip-cache-option) mix test
..

  1) test uses the correct responses when recorded with skip_cache enabled (ExVCR.SkipCacheTest)
     test/skip_cache_test.exs:32
     Assertion with != failed, both sides are exactly equal
     code: first_body != second_body
     left: "6740\n"
     stacktrace:
       test/skip_cache_test.exs:35: (test)

Also, I'm wondering if the response from www.random.org can be locally mocked instead of depending on external server. One example could be as follows.

diff --git a/test/skip_cache_test.exs b/test/skip_cache_test.exs
index 96ee042..daf4af5 100644
--- a/test/skip_cache_test.exs
+++ b/test/skip_cache_test.exs
@@ -5,6 +5,23 @@ defmodule ExVCR.SkipCacheTest do
   alias ExVCR.Mock
   alias ExVCR.Actor.Responses

+  @port 34007
+  @url 'http://localhost:#{@port}/server'
+
+  setup do
+    HttpServer.start(path: "/server", port: @port,
+      response: fn(_) ->
+        {200, [], to_string(:rand.uniform(10000))}
+      end
+    )
+
+    on_exit fn ->
+      HttpServer.stop(@port)
+    end
+
+    :ok
+  end
+
   test "skips cache when the skip_cache option is passed" do
     recorder = Recorder.start([skip_cache: true, fixture: "stubbed_request", adapter: ExVCR.Adapter.Httpc])
     Mock.mock_methods(recorder, ExVCR.Adapter.Httpc)
@@ -37,9 +54,8 @@ defmodule ExVCR.SkipCacheTest do
   end

   defp make_random_requests do
-    random_url = 'https://www.random.org/integers/?num=1&min=1&max=10000&col=1&base=10&format=plain&rnd=new'
-    {:ok, {_res, _headers, first_body}} = :httpc.request(random_url)
-    {:ok, {_res, _headers, second_body}} = :httpc.request(random_url)
+    {:ok, {_res, _headers, first_body}} = :httpc.request(@url)
+    {:ok, {_res, _headers, second_body}} = :httpc.request(@url)

     [first_body, second_body]
   end
(END)
rrpff commented 7 years ago

The skips_cache.json cassette should contain two responses. The test was originally run with the skip_cache option on, which I then removed after recording. It's supposed to show that the mock will use multiple responses if they're in the cassette, but that skip_cache doesn't need to be on for it to work.

You're right, it's not all that clear in the test. Any suggestions on how to make it more readable? Comments may do...

MUCH prefer using a local webserver, will update today to use that.

parroty commented 7 years ago

Thanks for explanation.

It's supposed to show that the mock will use multiple responses if they're in the cassette, but that skip_cache doesn't need to be on for it to work.

I don't have good answer, but if it's intended to manually customized cassette (rather than automatically recorded), one option might be to put under fixture/custom_cassettes.

rrpff commented 7 years ago

There shouldn't be a need to manually customise the JSON itself, it's more like there's a manual step involved in actually recording it.skip_cache will record the cassette as normal, it'll just ignore cache as it records, so every response is included.

Will have a think about this, haven't had time to update this PR yet.