I am calling a function from base in my code and I want to mock this function in my testthat
unit test.
How can I do this?
library(testthat)
my.func <- function() {
return(Sys.info()["sysname"]) # e. g. "Linux"
}
my.func()
# sysname
# "Linux"
test_that("base function can be mocked",
with_mock(
Sys.info = function() return(list(sysname = "Clever OS")), # see edit 2 !!!
expect_equal(my.func(), "Clever OS", fixed = TRUE)
)
)
# Error: Test failed: 'base function can be mocked'
# * my.func() not equal to "Clever OS".
?with_mock
says:
Functions in base packages cannot be mocked, but this can be worked around easily by defining a wrapper function.
I could encapsulate the base function call to Sys.info()
by a wrapper function that I call from my.func
then but let's assume I cannot do this because I am testing a function from a package that I cannot change...
Any solution for this?
I am using R3.4.4 64 Bit on Ubuntu 14.04 with testthat 2.0.0.9000.
Edit 1:
Using
`base::Sys.info` = function() return(list(sysname = "Clever OS"))
results in the testthat
error msg:
Can't mock functions in base packages (base)
Edit 2: As @suren show in his answer my code example here is wrong (the mocked function returns another class then the original one :-(
The correct mock function should be: Sys.info = function() return(c(sysname = "Clever OS"))
Sys.info
returns a character vector while my mock function returns a list so you have fixed my problem + it works now even to mock base functions. Either the help forwith_mock
is outdated or something else has changed. I will not update my wrong code example for consistency, please update your answer to correct my mock withSys.info = function() return(c(sysname = "Clever OS"))
. – Diley