使用`gh`包模拟API请求。

4

我正试图模拟gh API请求的输出:

httptest2::with_mock_dir("gh", {
  test_that("api works", {
    gh::gh("GET /repos/r-lib/gh")
  })
})

我正在尝试为经常调用GitHub API的自定义函数设置测试,并使用gh进行这些请求。我正在遵循这个教程作为指导:https://books.ropensci.org/http-testing/

然而,当运行此函数时未创建任何目录。是否有任何方法可以捕获 gh::gh 的输出并将其存储为模拟API返回,以便我可以在不需要GitHub身份验证甚至没有Internet连接的情况下运行我的测试?
2个回答

2
"httptest2" 是专门设计用于测试 "httr2" 请求的:

httptest2 is specifically designed to test httr2 requests:

该软件包有助于编写使用 httr2 的软件包的测试。

不幸的是,gh 使用 httr

Imports:
    cli (>= 3.0.1),
    gitcreds,
    httr (>= 1.2),
    ini,
    jsonlite

这意味着你不能直接使用httptest2gh
但是,通过使用gh源代码,你可以提取由gh发送到httrGET请求的参数:
gh_get <- function(endpoint, ..., per_page = NULL, .token = NULL, .destfile = NULL,
               .overwrite = FALSE, .api_url = NULL, .method = "GET",
               .limit = NULL, .accept = "application/vnd.github.v3+json",
               .send_headers = NULL, .progress = TRUE, .params = list()) {
  params <- c(list(...), .params)
  params <- gh:::drop_named_nulls(params)
  
  if (is.null(per_page)) {
    if (!is.null(.limit)) {
      per_page <- max(min(.limit, 100), 1)
    }
  }
  
  if (!is.null(per_page)) {
    params <- c(params, list(per_page = per_page))
  }
  
  req <- gh:::gh_build_request(
    endpoint = endpoint, params = params,
    token = .token, destfile = .destfile,
    overwrite = .overwrite, accept = .accept,
    send_headers = .send_headers,
    api_url = .api_url, method = .method
  )
  req
}

req <- gh_get("GET /repos/r-lib/gh")
req

#$method
#[1] "GET"

#$url
#[1] "https://api.github.com/repos/r-lib/gh"

#$headers
#                      User-Agent                           Accept 
#   "https://github.com/r-lib/gh" "application/vnd.github.v3+json" 

#$query
#NULL

#$body
#NULL

#$dest
#<request>
#Output: write_memory

这样做可以使用你提供的示例,使用httr2发送相同的请求:
library(httr2)
resp_httr2 <- request(base_url=req$url) %>%
              req_perform() %>%
              resp_body_json()



如果您主要关注的是 JSON 内容,结果是相同的,只是属性不同:
resp_gh <- gh::gh("GET /repos/r-lib/gh")

all.equal(resp_gh,resp_httr2,check.attributes=FALSE)
#[1] TRUE

如果你想使用httptest2,切换到httr2会起作用:
with_mock_dir("gh", {
   test_that("api works", {
   resp <- request(base_url=req$url) %>%
     req_perform() %>%
     resp_body_json()
     expect_equal(resp$full_name,"r-lib/gh")})
 })
#Test passed 
#[1] TRUE

离线测试现在可行,因为httptest2创建了gh\api.github.com目录。

0

也许你可以从tests/testthat/test-mock-repos.R中获得灵感。

res <- gh(
    TMPL("/repos/{owner}/{repo}"),
    owner = "gh-testing",
    repo = test_repo,
    .token = tt()
  )
  expect_equal(res$name, test_repo)
  expect_equal(res$description, "Test repo for gh")
  expect_equal(res$homepage, "https://github.com/r-lib/gh")
  expect_false(res$private)
  expect_false(res$has_issues)
  expect_false(res$has_wiki)

GET 方法不会创建任何目录。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接