我有一个包含建议依赖项的包,可启用可选行为。
遵循最佳实践,我在“建议”中添加了此依赖项,并在使用之前检查它是否已通过
requireNamespace
安装。
在这种特殊情况下,建议的包是
data.tree
并且可选行为是制作漂亮的打印而不是更无聊的打印。
myfun <- function(...) {
if (requireNamespace("data.tree", quietly = TRUE)) {
# do pretty print
} else {
# do boring print
}
}
我的问题是:如何使用
testthat
测试此行为?我想测试 if/else
的两个分支,但由于我确实安装了 data.tree,所以我只运行第一个分支。
test_that("myfun does a pretty print with data.tree", {
myfun()
})
test_that("myfun does a boring print if data.tree is not installed", {
# Ideally I am looking for a bit of code like this:
with(simulate_missing("data.tree"),
myfun())
})
有没有办法用
testthat
来模拟缺失的依赖关系,或者更一般地说是测试 myfun
的方法?
我能想到的唯一解决方案就是嘲笑,目前我不知道其他解决方案。
使用 testthat 包中的 with_mock() 函数模拟 requireNamespace()。这种方法允许您临时重新定义 requireNamespace() ,以便它返回 FALSE,就像未安装该包一样。
if (!requireNamespace("testthat", quietly = TRUE)) {
install.packages("testthat")
}
if (!requireNamespace("mockery", quietly = TRUE)) {
install.packages("mockery")
}
library(testthat)
library(mockery)
然后你必须编写一些这样的测试:
test_that("myfun does a pretty print with data.tree", {
# Assuming `requireNamespace` returns TRUE as `data.tree` is installed
expect_true(requireNamespace("data.tree", quietly = TRUE))
# Test the pretty print functionality
# You might want to capture output and expect certain content
output <- myfun()
expect_true(grepl("Expected pretty content", output))
})
test_that("myfun does a boring print if data.tree is not installed", {
# Mock `requireNamespace` to return FALSE for `data.tree`
with_mock(
`requireNamespace` = function(pkg, quietly = TRUE) {
if (pkg == "data.tree") {
return(FALSE)
}
# Call the real `requireNamespace` for other packages
base::requireNamespace(pkg, quietly = quietly)
},
{
# Now `myfun()` should behave as if `data.tree` is not installed
output <- myfun()
expect_true(grepl("Expected boring content", output))
}
)
})
我还没有在本地测试过它,你可能需要稍微调整一下,但我想分享这个概念。
干杯