问题
I am developing an R package and one of the function implements interaction with users through standard input via readline
. I now wonder how to test the behavior of this function, preferably with testthat
library.
It seems test_that
function assumes the answer is ""
for user-input. I wish I could test the behavior conditional of various answers users may type in.
Below is a small example code. In the actual development, the marryme
function is defined in a separate file and exported to the namespace.
devtools::test()
gets me an error on the last line because the answer never becomes yes. I would like to test if the function correctly returns true when user types "y"
.
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
})
回答1:
Use readLines() with a custom connection
By using readLines()
instead of readline()
, you can define the connection, which allows you to customize it using global options.
There are two steps that you need to do:
set a default option in your package in
zzz.R
that points to stdin:.onAttach <- function(libname, pkgname){ options(mypkg.connection = stdin()) }
In your function, change
readline
toreadLines(n = 1)
and set the connection inreadLines()
togetOption("mypkg.connection")
Example
Based on your 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) >
来源:https://stackoverflow.com/questions/41372146/test-interaction-with-users-in-r-package