Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

with_mock not working when inside test_that function #734

Closed
hannaET opened this issue Mar 23, 2018 · 7 comments
Closed

with_mock not working when inside test_that function #734

hannaET opened this issue Mar 23, 2018 · 7 comments

Comments

@hannaET
Copy link

hannaET commented Mar 23, 2018

I can't get the with_mock example to work when it is inside a test_that.
I tested it in a fresh R session (R version 3.4.3, testthat version 2.0.0)

> library(testthat)
> test_that("lalal", {
+ add_one <- function(x) x + 1
+ expect_equal(add_one(2), 3)
+ with_mock(
+   add_one = function(x) x - 1,
+   expect_equal(add_one(2), 1)
+ )
+ square_add_one <- function(x) add_one(x) ^ 2
+ expect_equal(square_add_one(2), 9)
+ expect_equal(
+   with_mock(
+     add_one = function(x) x - 1,
+     square_add_one(2)
+   ),
+   1
+ )})
Fehler: Test failed: 'lalal'
* Function add_one not found in environment testthat.
1: with_mock(add_one = function(x) x - 1, expect_equal(add_one(2), 1)) at :4
2: extract_mocks(new_values = new_values[!code_pos], .env = .env, eval_env = parent.frame())
3: lapply(stats::setNames(nm = mock_qual_names), function(qual_name) {
       pkg_name <- gsub(pkg_and_name_rx, "\\1", qual_name)
       if (is_base_pkg(pkg_name)) {
           stop("Can't mock functions in base packages (", pkg_name, ")", call. = FALSE)
       }
       name <- gsub(pkg_and_name_rx, "\\2", qual_name)
       if (pkg_name == "")
           pkg_name <- .env
       env <- asNamespace(pkg_name)
       if (!exists(name, envir = env, mode = "function"))
           stop("Function ", name, " not found in environment ", environmentName(env),
               ".", call. = FALSE)
       mock(name = name, env = env, new = eval(new_values[[qual_name]], eval_env, eval_env))
   })
4: FUN(X[[i]], ...)
5: stop("Function ", name, " not f
> add_one <- function(x) x + 1
> expect_equal(add_one(2), 3)
> with_mock(
+   add_one = function(x) x - 1,
+   expect_equal(add_one(2), 1)
+ )
> square_add_one <- function(x) add_one(x) ^ 2
> expect_equal(square_add_one(2), 9)
> expect_equal(
+   with_mock(
+     add_one = function(x) x - 1,
+     square_add_one(2)
+   ),
+   1
+ )
> test_that("doing",{
+ add_one <- function(x) x + 1
+ expect_equal(add_one(2), 3)
+ with_mock(
+   add_one = function(x) x - 1,
+   expect_equal(add_one(2), 1)
+ )
+ square_add_one <- function(x) add_one(x) ^ 2
+ expect_equal(square_add_one(2), 9)
+ expect_equal(
+   with_mock(
+     add_one = function(x) x - 1,
+     square_add_one(2)
+   ),
+   1
+ )})
Fehler: Test failed: 'doing'
* add_one(2) not equal to 1.
1/1 mismatches
[1] 3 - 1 == 2
* with_mock(add_one = function(x) x - 1, square_add_one(2)) not equal to 1.
1/1 mismatches
[1] 9 - 1 == 8
>

If someone could help me on that, it would be great.

@byapparov
Copy link

Does it work if you put add_one outside the test_that call?

@hannaET
Copy link
Author

hannaET commented Mar 26, 2018

actually, if I run in the console:

  add_one <- function(x) x + 1
 test_that("lala", {

   expect_equal(add_one(2), 3)
   f <- function() {}
   with_mock(
     add_one = function(x) x - 1,
     expect_equal(add_one(2), 1)
   )
 })

it works.
But if i run it via devtools::test() it fails (version: devtools_1.13.5)

@byapparov
Copy link

This is an expected behaviour.

Test that is trying to find function inside the package if test_package() is called:

env <- asNamespace(pkg_name)
if (!exists(name, envir = env, mode = "function")) 
  stop("Function ", name, " not found in environment ", 
               environmentName(env), ".", call. = FALSE)

If you want to test functions outside the package , you might try calling test_dir.

@hannaET
Copy link
Author

hannaET commented Mar 27, 2018

So now I have the function I want to mock inside the R folder of my package. When only I execute the expect_that & with_mock piece of code, the mocking works fine. However if I have the same code that I execute through devtools::test() it doesn't mock it and use the original implementation.
What I am doing wrong?

@byapparov
Copy link

@hannaET I cannot reproduce that using your code.

I have tried it with:

  • devtools 1.12.x and 1.13.5
  • testthat 2.0.0

@jimhester
Copy link
Member

It should work if you fully qualify the function name (include the pkgname).

e.g.

with_mock(
  "pkgname:::add_one" = function()

kaz-yos added a commit to kaz-yos/regmedint that referenced this issue Apr 25, 2020
- r-lib/testthat#734
- Need to specify the package name regmedint:::
- These are added as examples of how to check which functions are
  being called.
dpastoor pushed a commit to metrumresearchgroup/ghpm that referenced this issue Jun 11, 2020
@lorenzwalthert
Copy link

lorenzwalthert commented Aug 16, 2020

I suggest to add a note to the documentation for the requirement to fully qualify the function when used with devtools::test(). Should I make a PR for this?

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants