A few days ago, after fixing a bug, I decided to write more tests, to ensure the bug won't happen again. There was an old function, using cat() to indicate the different stages of processing. The corresponding tests used testthat::expect_output and expected the message from the cat() call.
Of course I was tempted to change the message, so the tests immediately failed. I realized there must be a better way. A look at the documentation helped me with this issue.
?testthat::expect_output
The documentation for testthat::expect_output() suggests using testthat::expect_snapshot(), but I'd rather avoid having additional files if not absolutely necessary.
This is what I used in the end:
rlang --- testthat
rlang::inform() --- testthat::expect_condition()
rlang::warn() --- testthat::expect_warning()
rlang::abort() --- testthat::expect_error()
create_special_file <- function(df, output_path) {
checkmate::assert_directory_exists(dirname(output_path))
if (checkmate::test_file_exists(output_path)) {
rlang::warn(
message = paste("The file", output_path, "already exists"),
class = "file-exists"
)
return(invisible(NULL))
}
rlang::inform(
message = "Process data.frame",
class = "process-df"
)
if (nrow(df) == 0) {
rlang::abort(
message = "empty data.frame, nothing to do",
class = "empty-data.frame"
)
}
# do the work
}
testthat::test_that(
desc = "create_special_file: file exists",
code = {
output_path <- tempfile(fileext = ".csv")
testthat::expect_warning(
object = mockthat::with_mock(
`checkmate::test_file_exists` = TRUE,
{
create_special_file(df = mtcars, output_path = output_path)
}
),
class = "file-exists"
)
}
)
testthat::test_that(
desc = "create_special_file: process df",
code = {
output_path <- tempfile(fileext = ".csv")
testthat::expect_condition(
object = {
create_special_file(df = mtcars, output_path = output_path)
},
class = "process-df"
)
}
)
testthat::test_that(
desc = "create_special_file: empty-data.frame",
code = {
output_path <- tempfile(fileext = ".csv")
testthat::expect_error(
object = {
create_special_file(df = data.frame(), output_path = output_path)
},
class = "empty-data.frame"
)
}
)
Make a promise. Show up. Do the work. Repeat.