如何在R testthat中全局替换包内部数据为模拟数据?
全局替换R包内部数据集用于单元测试
问题场景
我开发的R包通过usethis::use_data(internal = TRUE)创建了内部数据集df,并保存到R/sysdata.rda中。编写单元测试时,希望全局替换这个内部data.frame为模拟数据,但尝试在test/testthat/setup.R中使用local_mocked_bindings、assign或withr::local_environment均无效。仅将local_mocked_bindings代码写在单个test_that函数或测试文件内时才生效,无法覆盖所有测试。
包结构简化如下:
create_data.R(生成内部数据)
# Internal package data df <- data.frame(test = c(1, 2, 3)) usethis::use_data(df, internal = TRUE)
R/show_me_values.R(待测试函数)
# This the function I wish to test show_me_values <- function() { return(df) }
test/testthat/test-show_me_values.R(测试用例)
test_that("Test that my function uses mock data", { expect_equal(show_me_values(), data.frame(test = c(1, 1, 1))) })
解决方案
问题核心在于:内部数据集df存储在包的命名空间中,默认local_mocked_bindings仅修改当前环境的绑定,无法触及包命名空间。只需在setup.R中指定env参数指向包的命名空间即可实现全局替换:
修改后的test/testthat/setup.R
# 全局替换包内部的df为模拟数据 testthat::local_mocked_bindings( df = data.frame(test = c(1, 1, 1)), env = asNamespace("你的包名称") # 替换为实际的包名 )
原理说明
asNamespace("你的包名称")获取包的命名空间环境,local_mocked_bindings通过env参数将模拟数据绑定到该环境中,覆盖原有的内部数据集。- 该设置会在所有测试启动前生效,所有测试文件中的函数调用都会使用模拟后的
df。
内容的提问来源于stack exchange,提问作者Emil Lykke Jensen
相关产品推荐
相关产品推荐

