Reputation: 6979
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.
request
refers to the definition of http request that will be done inside of the api wrapper function;response
refers to the response object that has been cached for the purpose of mocking.Upvotes: 5
Views: 909
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
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