Skip to content

Commit

Permalink
Better approach for mocking base functions (#1853)
Browse files Browse the repository at this point in the history
  • Loading branch information
hadley authored Sep 18, 2023
1 parent f3acaf4 commit bccc249
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 10 deletions.
24 changes: 19 additions & 5 deletions R/mock2.R
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,21 @@
#'
#' ## Base functions
#'
#' Note that it's not possible to mock functions in the base namespace
#' (i.e. functions that you can use without explicitly importing them)
#' since currently we don't know of a way to to mock them without potentially
#' affecting all running code. If you need to mock a base function, you'll
#' need to create a wrapper, as described below.
#' To mock a function in the base package, you need to make sure that you
#' have a binding for this function in your package. It's easiest to do this
#' by binding the value to `NULL`. For example, if you wanted to mock
#' `interactive()` in your package, you'd need to include this code somewhere
#' in your package:
#'
#' ```R
#' interactive <- NULL
#' ```
#'
#' Why is this necessary? `with_mocked_bindings()` and `local_mocked_bindings()`
#' work by temporarily modifying the bindings within your package's namespace.
#' When these tests are running inside of `R CMD check` the namespace is locked
#' which means it's not possible to create new bindings so you need to make sure
#' that the binding exists already.
#'
#' ## Namespaced calls
#'
Expand Down Expand Up @@ -232,6 +242,10 @@ test_mock_method.integer <- function(x) {
"y"
}

test_mock_base <- function() {
interactive()
}
interactive <- NULL

show_bindings <- function(name, env = caller_env()) {
envs <- env_parents(env)
Expand Down
19 changes: 14 additions & 5 deletions man/local_mocked_bindings.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions tests/testthat/test-mock2.R
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,7 @@ test_that("can't mock bindings that don't exist", {
expect_snapshot(local_mocked_bindings(f = function() "x"), error = TRUE)
})

test_that("can mock base functions with in-package bindings", {
local_mocked_bindings(interactive = function() TRUE)
expect_equal(test_mock_base(), TRUE)
})

0 comments on commit bccc249

Please sign in to comment.