R Y*_*oda 12 r mocking testthat
我在我的代码中从base调用一个函数,我想在我的testthat单元测试中模拟这个函数.
我怎样才能做到这一点?
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 说:
无法模拟基础包中的函数,但可以通过定义包装函数轻松解决此问题.
我可以Sys.info()通过我my.func从那时调用的包装器函数来封装基函数调用,但我们假设我不能这样做,因为我正在测试一个我无法更改的包中的函数...
对此有何解决方案?
我在Ubuntu 14.04上使用R3.4.4 64位,testthat为2.0.0.9000.
编辑1:
运用
`base::Sys.info` = function() return(list(sysname = "Clever OS"))
导致testthat错误消息:
无法模拟基础包中的函数(基础)
编辑2:由于@suren在他的回答中显示我的代码示例在这里是错误的(模拟函数返回另一个类然后原始的:-(
正确的模拟函数应该是: Sys.info = function() return(c(sysname = "Clever OS"))
错误消息是my.func()不等于"Clever OS"..原因是在模拟Sys.info函数a时返回命名的字符向量list.
只需修改模拟函数和期望值,它就可以工作:
test_that("base function can be mocked",
  with_mock(
    Sys.info = function() return(c(sysname = "Clever OS")),
    expect_equal(my.func(), c(sysname = "Clever OS"), fixed = TRUE)
  )
)
这甚至可以在包中使用.
注意:基本功能的模拟不应该根据帮助而起作用,with_mock但它确实(至少目前).
以下(my.func()$`sysname`)似乎通过问题的原始代码传递测试.
test_that("base function can be mocked",
          with_mock(
            Sys.info = function() return(list(sysname = "Clever OS")), 
            expect_equal(my.func()$`sysname`, "Clever OS", fixed = TRUE)
          )
)
或者,有一个列表中的字符串 expect_equal
test_that("base function can be mocked",
          with_mock(
            Sys.info = function() return(list(sysname = "Clever OS")),  
            expect_equal(my.func(), list(`sysname` = "Clever OS"), fixed = TRUE)
          )
)
| 归档时间: | 
 | 
| 查看次数: | 478 次 | 
| 最近记录: |