tl;博士
require(knitr)要测试使用失败时遵循的分支,请使用trace()临时修改require()以便它不会找到knitr,即使它存在于.libPaths(). 具体来说,在 的正文中require(),将 的值重置lib.loc=为指向R.home()-- 一个不包含knitr包的现有目录。
这似乎在包中和在运行以下命令的交互式会话中一样有效:
find.package("knitr")
trace("require", quote(lib.loc <- R.home()), at=1)
isTRUE(suppressMessages(suppressWarnings(require(knitr))))
untrace("require")
isTRUE(suppressMessages(suppressWarnings(require(knitr))))
据我了解,您有一个具有两个分支的函数,一个在require(knitr)成功的 R 会话中执行,另一个在失败的会话中执行。然后,您希望从knitr实际上打开的单个 R 实例“双向”测试此功能.libPaths()。
所以基本上你需要一些方法来暂时隐藏对knitrrequire(knitr)实际存在的调用。完全暂时重置看起来很有希望的返回值,但似乎不可能。.libPaths()
另一个有希望的途径是以某种方式将lib.locin 调用的默认值重置为require()from NULL(这意味着“使用 的值)到knitr.libPaths()不可用的其他位置。你不能通过覆盖来实现这一点,也不能(在包中)可以您可以通过定义具有所需值 的本地掩码版本来到达那里。base::require()require()lib.loc
不过,看起来您可以使用trace()to 临时修改require()(通过设置将其蒙蔽到knitr的可用性lib.loc=R.home())。然后untrace()恢复require()到香草版本,它将继续找到knitr。
这是我测试过的虚拟包中的样子。首先是一个 R 函数,它允许我们沿着两个分支测试是否成功
## $PKG_SRC/R/hello.R
hello <- function(x=1) {
if(require(knitr)) {
x==2
} else {
x==3
}
}
然后是几个测试,每个分支一个:
## $PKG_SRC/inst/tests/testme.R
## Test the second branch, run when require(knitr) fails
trace("require", quote(lib.loc <- R.home()), at=1)
stopifnot(hello(3))
untrace("require")
## Test the first branch, run when require(knitr) succeeds
stopifnot(hello(2))
为了测试这一点,我pkgKitten::kitten("dummy")以前设置了一个源目录,将这两个文件复制进去,添加Suggests: knitr到文件中,DESCRIPTION然后从相应的目录中运行。该软件包安装得很好,并通过了所有检查。devtools::install()devtools::check()