I have some delicate issues with environments that are currently manifesting themselves in my unit tests. My basic structure is this
- I have a main function
main
that has many arguments wrapper
is a wrapper function (one of many) that pertains only to selected arguments ofmain
helper
is an intermediate helper function that is used by all wrapper functions
I use eval
and match.call()
to move between wrappers and the main function smoothly. My issue now is that my tests work when I run them line by line, but not using test_that()
.
Here is a MWE that shows the problem. If you step through the lines in the test manually, the test passes. However, evaluating the whole test_that()
chunk the test fails because one of the arguments can not be found.
library(testthat)
wrapper <- function(a, b) {
fun_call <- as.list(match.call())
ret <- helper(fun_call)
return(ret)
}
helper <- function(fun_call) {
fun_call[[1]] <- quote(main)
fun_call <- as.call(fun_call)
fun_eval <- eval(as.call(fun_call))
return(fun_eval)
}
main <- function(a, b, c = 1) {
ret <- list(a = a, b = b, c = c)
return(ret)
}
test_that("Test", {
a <- 1
b <- 2
x <- wrapper(a = a, b = b)
y <- list(a = 1, b = 2, c = 1)
expect_equal(x, y)
})
With quite some confidence, I suspect I need to modify the default environment used by eval
(i.e. parent.frame()
), but I am not sure how to do this.