admin管理员组

文章数量:1420159

I have a function which is being called in multiple functions. All of them sit in separate files. Let's take an example to understand it.

# R/generic_function.R
generic_function <- function() {
....
....
}

# R/functionA.R
function_A <- function() {
...
generic_function()
...
}

# R/functionB.R
function_B <- function() {
...
generic_function()
...
}

I am writing tests for them using testthat in corresponding test files where I am mocking the generic_function()

# tests/testthat/test-functionA.R
mockery::stub(function_A, "generic_function", TRUE)
...
...


# tests/testthat/test-functionB.R
mockery::stub(function_B, "generic_function", TRUE)
...
....

There are too many such function* files and corresponding test-function* files. I am wondering if there is a way where I can mock such files on global level only once?

I have a function which is being called in multiple functions. All of them sit in separate files. Let's take an example to understand it.

# R/generic_function.R
generic_function <- function() {
....
....
}

# R/functionA.R
function_A <- function() {
...
generic_function()
...
}

# R/functionB.R
function_B <- function() {
...
generic_function()
...
}

I am writing tests for them using testthat in corresponding test files where I am mocking the generic_function()

# tests/testthat/test-functionA.R
mockery::stub(function_A, "generic_function", TRUE)
...
...


# tests/testthat/test-functionB.R
mockery::stub(function_B, "generic_function", TRUE)
...
....

There are too many such function* files and corresponding test-function* files. I am wondering if there is a way where I can mock such files on global level only once?

Share Improve this question asked Jan 29 at 6:16 user16024709user16024709 1333 silver badges17 bronze badges 2
  • I don’t know how ‘mockery’ works but you should only need to mock one function: the one calling all the others (if A calls B and B calls generic_function, then mocking only A should work, unless ‘mockery’ uses a questionable design). Of course if you are calling function_A, function_B, etc. individually from your tests, that won’t help you. — But you could write a helper call_mocked() and then use that inside your tests; i.e. instead of calling function_A(…), you’d use call_mocked(function_A, …) for example. – Konrad Rudolph Commented Jan 29 at 7:58
  • You might try putting testthat::local_mocked_bindings(generic_function = \(…) TRUE) in "tests/testthat/helpers.R" or "tests/testthat/setup.R"? – zephryl Commented Jan 29 at 12:19
Add a comment  | 

1 Answer 1

Reset to default 0

I solved it using setup.R and teardown.R files. These files are special and have a some special characteristics.

setup.R file is ran before every test file. In setup.R we replace generic_function with mock_generic_function in global environment.

# tests/testthat/setup.R
mock_generic_function <- function(...) {
  TRUE
}
message("Running setup.R before the test...")
assign("generic_function ", mock_generic_function , envir = globalenv())

teardown.R is ran after all the tests are run where we remove the (mocked) generic_function from global environment.

rm(generic_function, envir = globalenv())
message("Running teardown.R after the tests have been executed...")

PS - From the help file, the usage of setup and teardown is superseded however, this approach works well for me so I am using this for time being.

本文标签: rHow can I mock a function globally using testthatStack Overflow