# Mocking writing to disk

#### Scott Chamberlain

#### 2023-06-24

# Request matching

    library("vcr")

If you have http requests for which you write the response to disk, then use `vcr_configure()` to set the `write_disk_path` option. See more about the write_disk_path configuration option in `vignette("configuration", package = "vcr")`.

Here, we create a temporary directory, then set the fixtures

    tmpdir <- tempdir()
    vcr_configure(
      dir = file.path(tmpdir, "fixtures"),
      write_disk_path = file.path(tmpdir, "files")
    )
    #> <vcr configuration>
    #>   Cassette Dir: /var/folders/vw/4nm3x1ld0_jgmqy6_yf6pz3c0000gn/T//Rtmp2RAJj1/fixtures
    #>   Record: new_episodes
    #>   Serialize with: yaml
    #>   URI Parser: urltools::url_parse
    #>   Match Requests on: query, headers
    #>   Preserve Bytes?: TRUE
    #>   Logging?: FALSE
    #>   ignored hosts: google.com
    #>   ignore localhost?: TRUE
    #>   Write disk path: /var/folders/vw/4nm3x1ld0_jgmqy6_yf6pz3c0000gn/T//Rtmp2RAJj1/files

Then pass a file path (that doesn’t exist yet) to crul’s `disk` parameter. `vcr` will take care of handling writing the response to that file in addition to the cassette.

    library(crul)
    ## make a temp file
    f <- tempfile(fileext = ".json")
    ## make a request
    cas <- use_cassette("test_write_to_disk", {
      out <- HttpClient$new("https://httpbin.org/get")$get(disk = f)
    })
    file.exists(out$content)
    #> [1] TRUE
    out$parse()
    #> [1] "{\n  \"args\": {}, \n  \"headers\": {\n    \"Accept\": \"application/json, text/xml, application/xml, */*\", \n    \"Accept-Encoding\": \"gzip, deflate\", \n    \"Host\": \"httpbin.org\", \n    \"User-Agent\": \"libcurl/7.88.1 r-curl/5.0.1 crul/1.4.0\", \n    \"X-Amzn-Trace-Id\": \"Root=1-6497bdd8-26fb8f29590d18d7133665a1\"\n  }, \n  \"origin\": \"97.113.160.57\", \n  \"url\": \"https://httpbin.org/get\"\n}\n"

This also works with `httr`. The only difference is that you write to disk with a function `httr::write_disk(path)` rather than a parameter.

Note that when you write to disk when using `vcr`, the cassette is slightly changed. Instead of holding the http response body itself, the cassette has the file path with the response body.

    http_interactions:
    - request:
        method: get
        uri: https://httpbin.org/get
      response:
        headers:
          status: HTTP/1.1 200 OK
          access-control-allow-credentials: 'true'
        body:
          encoding: UTF-8
          file: yes
          string: /private/var/folders/fc/n7g_vrvn0sx_st0p8lxb3ts40000gn/T/Rtmp5W4olr/files/file177e2e5d97ec.json

And the file has the response body that otherwise would have been in the `string` yaml field above:

    {
      "args": {},
      "headers": {
        "Accept": "application/json, text/xml, application/xml, */*",
        "Accept-Encoding": "gzip, deflate",
        "Host": "httpbin.org",
        "User-Agent": "libcurl/7.54.0 r-curl/4.3 crul/0.9.0"
      },
      "origin": "24.21.229.59, 24.21.229.59",
      "url": "https://httpbin.org/get"
    }

## More documentation

Check out the http testing book for a lot more documentation on `vcr`, `webmockr`, and `crul`