Bulat
Bulat

Reputation: 6979

How to mock http response of rest API?

I am looking for the easiest way to mock response of rest API within testthat framework.

Example of usage would be similar to this:

with_mock_api(
  request, 
  response, 
  {
      call_to_function_with_api_call()
      # expectations check
  }
)

As a result, tests will pass without calling the real API.

Upvotes: 5

Views: 909

Answers (2)

Bulat
Bulat

Reputation: 6979

There is also httptest package that provides mocking functionality for http requests in R.

Adding with_mock_api() to your tests is straightforward. If we wrap the code in with_mock_api(), actual requests won't happen.

with_mock_api({
    test_that("Requests happen", {
        expect_s3_class(GET("http://httpbin.org/get"), "response")
        expect_s3_class(
            GET("http://httpbin.org/response-headers",
                query=list(`Content-Type`="application/json")),
            "response"
        )
    })
})

Upvotes: 1

sckott
sckott

Reputation: 5903

https://github.com/ropensci/vcr makes this pretty easy. Supports integration with crul as well as httr.

A function that makes an API request

foo_bar <- function() {
  x <- crul::HttpClient$new("https://httpbin.org")
  res <- x$get("get", query = list(foo = "bar"))
  jsonlite::fromJSON(res$parse("UTF-8"))
}

Then run any functions inside of a vcr::use_cassette block, and run any testthat expectations on the output as usual

library(testthat)
test_that("my_test", {
  vcr::use_cassette("foo_bar", {
    aa <- foo_bar()
  })

  expect_is(aa, "list")
  expect_named(aa, c("args", "headers", "origin", "url"))
  expect_equal(aa$args$foo, "bar")
})

The request and response gets stored in a yaml file - see https://github.com/ropensci/vcr#usage for an example. - On the 1st run of the code above, a real HTTP request will be made to make that yaml file, BUT on the 2nd and all subsequent runs afterwards, no real HTTP requests are made, but instead the function uses that yaml file.

Upvotes: 5

Related Questions