我有一个这样的功能:
func <- function(x) {
if (requireNamespace("broom", quietly = TRUE)) {
print(1)
} else {
print(2)
}
Run Code Online (Sandbox Code Playgroud)
我想使用testthat触发两种情况编写测试。但是,当然broom我的计算机上已经安装或未安装。该怎么办?
编辑:从此不再有效testthat-2.0.0。根据2017年10月的更改:
其余的答案仅适用于的旧版本testthat。
testthat::with_mock 应该做你想做的。
library(testthat)
somefunc <- function() if (requireNamespace("base", quietly=TRUE)) 1L else 2L
Run Code Online (Sandbox Code Playgroud)
一些简单的测试:
expect_equal( somefunc(), 1L )
Run Code Online (Sandbox Code Playgroud)
成功了
expect_equal( somefunc(), 2L )
# Error: somefunc() not equal to 2.
# 1/1 mismatches
# [1] 1 - 2 == -1
Run Code Online (Sandbox Code Playgroud)
预期。
让我们创建一个覆盖基本函数的“模拟”函数:
with_mock(
`base::requireNamespace` = function(package, ..., quietly=FALSE) FALSE,
expect_equal( somefunc(), 1L )
)
# Error: somefunc() not equal to 1.
# 1/1 mismatches
# [1] 2 - 1 == 1
with_mock(
`base::requireNamespace` = function(package, ..., quietly=FALSE) FALSE,
expect_equal( somefunc(), 2L )
)
# [1] 2
Run Code Online (Sandbox Code Playgroud)
注意:成功后,将expect_equal无形地返回返回值,因此[1] 1在第一个示例中看不到。with_mock成功时会返回返回值,但不会隐式返回。在这两种情况下,失败都会返回修改后的返回值。此微小差异不应影响任何测试。
根据您要覆盖的功能,对我而言,谨慎定义具有相同形式的模拟功能是有意义的。如果您确切地知道在测试期间所有从属函数中总是如何调用它,则可以简化此操作,但是我认为对形式的额外关注将排除真正难以解决的测试失败。
注意:帮助指出
...仍处于实验阶段,请谨慎使用。