捕获警告并一次性赋值?

Capture warnings and assign a value in one go?

我正在 运行 使用 testthat 包进行一些单元测试。我有一个在各种条件下反复测试的功能。我的问题是函数有3种"outputs":

  1. 打印到控制台。这应该被丢弃。
  2. 有时会发出警告。测试应该通过特定的警告,但对于其他人则失败。
  3. Returns一个值。我想保存它以供进一步测试。

有办法吗?我无法更改有问题的功能,因为它与另一个包一起提供。

这是一个简单的 repex:

func = function() {
  print("a print")
  warning("a warning")
  return("a value")
}

我可以通过

完成(1)和(3)
capture.output(result <<- func())
# result can be tested here, but the warning is not captured

我可以通过

来完成 (1) 和 (2)
msg = testthat::capture_warning(capture.output(result <<- func()))
if (!is.null(msg$message)) {
   testthat::expect_true(msg$message == "a warning")
}
# result is undefined here

同样,有没有办法实现上述所有三个目标?

使用 purrr 包中的 quietly,您可以捕获警告、打印、消息、输出,同时仍然返回一个值。

然后,您可以围绕它构建一个包装函数来开发您的检查和条件。

func <- function() {
  print("a print")
  warning("a warning")
  return("a value")
}

library(purrr)

res <- quietly(func)()
res

# $result
# [1] "a value"
#
# $output
# [1] "[1] \"a print\""
#
# $warnings
# [1] "a warning"
#
# $messages
# character(0)

quietly 是一种函数装饰器。