我正在开发一个R包,其中一个函数通过readline
标准输入实现与用户的交互。我现在想知道如何测试这个函数的行为,最好用testthat
库。
似乎test_that
函数假定用户输入的答案为""
。我希望我可以测试用户可能输入的各种答案条件下的行为。
下面是一个小示例代码。在实际开发中,marryme
函数在单独的文件中定义并导出到命名空间。
devtools::test()
在最后一行收到错误,因为答案永远不会变为是。我想在用户输入"y"
时测试函数是否正确返回true。
library(testthat)
test_that("input", {
marryme <- function() {
ans <- readline("will you marry me? (y/n) > ")
return(ans == "y")
}
expect_false(marryme()) # this is good
expect_true(marryme()) # this is no good
})
答案 0 :(得分:4)
使用readLines()
代替readline()
,您可以定义连接,允许您使用全局选项对其进行自定义。
您需要执行两个步骤:
在zzz.R
中的包中设置一个默认选项,指向stdin:
.onAttach <- function(){
options(mypkg.connection = stdin())
}
在您的函数中,将readline
更改为readLines(n = 1)
并将readLines()
中的连接设置为getOption("mypkg.connection")
根据您的MWE:
library(testthat)
options(mypkg.connection = stdin())
marryme <- function() {
cat("will you marry me? (y/n) > ")
ans <- readLines(con = getOption("mypkg.connection"), n = 1)
cat("\n")
return(ans == "y")
}
test_that("input", {
f <- file()
options(mypkg.connection = f)
ans <- paste(c("n", "y"), collapse = "\n") # set this to the number of tests you want to run
write(ans, f)
expect_false(marryme()) # this is good
expect_true(marryme()) # this is no good
# reset connection
options(mypkg.connection = stdin())
# close the file
close(f)
})
#> will you marry me? (y/n) >
#> will you marry me? (y/n) >