我有这样的功能:
func <- function(x) {
if (requireNamespace("broom", quietly = TRUE)) {
print(1)
} else {
print(2)
}
我想使用testthat
编写触发两种情况的测试。但是当然broom
是安装在我的计算机上还是没有安装。该怎么办?
答案 0 :(得分:4)
编辑:此功能自/usr/local/bin/mup
起不再有效。根据{{3}}:
- “无法在基本程序包中模拟函数”:您不能再使用
#count ,date 98.000000, 2014-03-16 267.000000, 2014-03-23 298.000000, 2014-03-30 313.000000, 2014-04-06 225.000000, 2014-04-13 226.000000 2014-04-20
在基本程序包中模拟函数,因为由于字节码编译器的更改,它在R-devel中不再起作用。我建议改为使用change in Oct 2017或mockery。
其余答案仅适用于testthat-2.0.0
的旧版本。
with_mock()
应该做您想要的。
testthat
一些简单的测试:
testthat::with_mock
成功。
library(testthat)
somefunc <- function() if (requireNamespace("base", quietly=TRUE)) 1L else 2L
预期。
让我们创建一个覆盖基本功能的“模拟”功能:
expect_equal( somefunc(), 1L )
注意:成功后,expect_equal( somefunc(), 2L )
# Error: somefunc() not equal to 2.
# 1/1 mismatches
# [1] 1 - 2 == -1
会无形地返回返回值,因此在第一个示例中看不到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
。 expect_equal
成功时会返回返回值,但不会隐式返回。在这两种情况下,失败都会返回修改后的返回值。这一微小差异不会影响任何测试。
根据您要重写的函数,对我而言,谨慎定义具有相同形式的模拟函数是有意义的。如果您确切地知道 在测试期间在 all 下级函数中总是 调用的方式,则可以简化此操作,但我认为这是多余的仔细注意形式会避免真正难以解决的测试失败。
NB:帮助说明:
...仍处于实验阶段,请谨慎使用。
答案 1 :(得分:0)
old_fn <- base::requireNamespace
myrequireNamespace <- function(...) FALSE
unlockBinding("requireNamespace", as.environment("package:base"))
assign("requireNamespace",myrequireNamespace, "package:base")
expect_error(read_data("meta",data_table, frame=NULL),"Package \"readxl\"
needed for this function to load excel files")
assign("requireNamespace",old_fn, "package:base")
lockBinding("requireNamespace", as.environment("package:base"))
rm(old_fn, myrequireNamespace)
对我来说是一种解决方法,它确实可以在testthat内部工作。