R tryCatch与testthat期望

时间:2016-06-16 23:24:59

标签: r testthat

我有以下功能:

fun = function(expr) {
  mc = match.call()

  env = as.environment(within(
    list(),
    expr = eval(mc$expr)
  ))

  return(env)
}

tryCatch()内调用,以便expr中的任何错误条件得到优雅处理。

它在标准错误条件下正常工作:

tryCatch({
  fun({
    stop('error')
  })
}, error = function(e) {
  message('error happened')
})

# error happened

但是,它不会捕获testthat期望错误(这是我特定用例的首选):

library(testthat)

tryCatch({
  fun({
    expect_true(FALSE)
  })
}, error = function(e) {
  message('expectation not met')
})

# Error: FALSE isn't true.

或更简单:

library(testthat)

tryCatch({
  expect_true(FALSE)
}, error = function(e) {
  message('expectation not met')
})

# Error: FALSE isn't true.

没有捕捉到期望错误。

此问题在从R 3.2.2升级到R 3.3.0之后出现 - 即期望错误在R 3.2.2中被捕获。

是否有办法让R {3.3}中testthat抓住tryCatch()期望?

1 个答案:

答案 0 :(得分:8)

我在expect()上设置了调试器,然后逐步执行了几行代码(为了简洁而编辑了输出),并查看了已发出信号的类的类

> debug(expect)
> xx = expect_true(FALSE)
...
Browse[2]> n
debug: exp <- as.expectation(exp, ..., srcref = srcref)
Browse[2]>
...
Browse[2]> class(exp)
[1] "expectation_failure" "expectation"         "condition"   
Browse[2]> Q
> undebug(expect)       

因此它不是类'错误'的条件,并且可以被明确捕获

> tryCatch(expect_true(FALSE), expectation_failure=conditionMessage)
[1] "FALSE isn't true.\n"

你也可以抓住expectation班。

重启允许你继续,如果这在某种程度上很重要。

result <- withCallingHandlers({
    expect_true(FALSE)
    expect_true(!TRUE)
    expect_true("this sentence")
}, expectation_failure=function(e) {
    cat(conditionMessage(e))
    invokeRestart("continue_test")
})

带输出

FALSE isn't true.
!TRUE isn't true.
"this sentence" isn't true.
> result
[1] FALSE

人们也可以抓住或处理成功

> tryCatch(expect_true(TRUE), expectation_success=class)
[1] "expectation_success" "expectation"         "condition"