如何模拟 rest API 的 http 响应?

How to mock http response of rest API?

我正在寻找在 testthat 框架内模拟其余 API 响应的最简单方法。

用法示例与此类似:

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

因此,测试将通过而无需调用真正的 API。

https://github.com/ropensci/vcr 让这变得非常简单。支持与 crul 以及 httr 的集成。

发出 API 请求的函数

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

然后 运行 vcr::use_cassette 块内的任何函数,以及 运行 任何对输出的预期如往常一样的测试

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")
})

请求和响应存储在一个 yaml 文件中 - 有关示例,请参见 https://github.com/ropensci/vcr#usage。 - 在上面代码的第 1 天 运行,将发出一个真正的 HTTP 请求来生成该 yaml 文件,但是在第 2 天和之后的所有后续 运行 中,不会发出真正的 HTTP 请求,但是相反,该函数使用该 yaml 文件。

还有 httptest 包为 R 中的 http 请求提供模拟功能。

将 with_mock_api() 添加到您的测试中非常简单。如果我们将代码包装在 with_mock_api() 中,实际请求将不会发生。

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"
        )
    })
})