testthat::with_mock problem

201 views
Skip to first unread message

Łukasz A. Bartnik

unread,
Sep 18, 2014, 10:06:39 AM9/18/14
to rdev...@googlegroups.com

Hi, nice to meet you all!

I am trying to use with_mock right now and this is what happens. (my environment is described at the end of this post)

(1) with_mock(testthat::auto_test=function(...)2, base::cat=function(...)3, {print(auto_test);print(cat);T})

As far as I understand, this line should print two mocked functions. Instead, it produces the original testthat::auto_test

with_mock(testthat::auto_test=function(...)2, base::cat=function(...)3, {print(auto_test);print(cat);T}) 
function (code_path, test_path, reporter = "summary", env = test_env()) 
{
reporter <- find_reporter(reporter)
[many lines removed]
}

function(...)3

[1] TRUE

(2) with_mock(plyr::alply=function(...)2, base::cat=function(...)3, {print(alply);print(cat);T})

Without plyr loaded this line produces an error message: "Error in print(alply) : object 'alply' not found"
If I load plyr, I get its original alply body instead of my mock.

(3) I've tried to understand if I'm using your code in the right way. The only thing that I saw and that surprised was the result of calling asNamespace('plyr') when plyr is not yet loaded:

asNamespace('plyr')

(4) I have check also that after loading this particular package asNamespace seems to be returning the correct environment:

> library(plyr)
> identical(asNamespace('plyr'), environment(alply))
[1] TRUE

When I try to overwrite anything in this environment, R doesn't allow me to, unless I call unlockBinding.

> x=environment(alply)
> y=asNamespace('plyr')
> y$alply<-1
Error in y$alply <- 1 : cannot change value of locked binding for 'alply'
> unlockBinding('alply',y)
> y$alply<-1
> x$alply
[1] 1

As you can see, both x and y refer to the same object alply.

But when I try to read its value from the global env, I get the original value:

> alply
function (.data, .margins, .fun = NULL, ..., .expand = TRUE,
[many lines removed]
<environment: namespace:plyr>

(5) Is there something I should do to be able to mock functions in the plyr package?

(6) environment
R version 3.1.1 (2014-07-10)
Linux ubuntu 3.13.0-35-generic #62-Ubuntu SMP Fri Aug 15 01:58:42 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

testthat$ git pull
Already up-to-date.
testthat$ git status
On branch master
Your branch is up-to-date with 'origin/master'.

nothing to commit, working directory clean
testthat$ cd .. && R CMD INSTALL testthat

  • installing to library ‘~/R/x86_64-pc-linux-gnu-library/3.1’

I'm loading testhat with this line:

library(testthat, lib.loc='~/R/x86_64-pc-linux-gnu-library/3.1/')

kirill...@gmail.com

unread,
Sep 18, 2014, 10:12:46 AM9/18/14
to rdev...@googlegroups.com
I think this is a feature that hasn't been tested and doesn't work as expected:

> library(plyr)
> testthat::with_mock(`plyr::adply`=function(...)2, get("adply", asNamespace("plyr")))
function(...)2
<environment: 0x32d9c20>
> testthat::with_mock(`plyr::adply`=function(...)2, get("adply"))
function (.data, .margins, .fun = NULL, ..., .expand = TRUE, 
    .progress = "none", .inform = FALSE, .parallel = FALSE, .paropts = NULL) 
{
    pieces <- splitter_a(.data, .margins, .expand)
    ldply(.data = pieces, .fun = .fun, ..., .progress = .progress, 
        .inform = .inform, .parallel = .parallel, .paropts = .paropts)
}
<environment: namespace:plyr>

In practice, this means that you can mock a function in a package and test packaged code that accesses this package (as shown in the tests), but for some reason unqualified accesses to code from loaded packages don't work correctly.

I'll take a look at it, probably an issue for the testthat package should be filed.

Łukasz A. Bartnik

unread,
Sep 18, 2014, 10:15:28 AM9/18/14
to rdev...@googlegroups.com
The thing is the problem originated when I was trying to mock a function in a test. I intended the code in my first email to be a simplified version of that test.

Lukasz

kirill...@gmail.com

unread,
Sep 18, 2014, 10:19:38 AM9/18/14
to rdev...@googlegroups.com
It should work if you used qualified access to that function, in this example, plyr::adply instead of simply adply:

> testthat::with_mock(`plyr::adply`=function(...)2, plyr::adply)
function(...)2
<environment: 0x3327420>


-Kirill

kirill...@gmail.com

unread,
Sep 18, 2014, 6:51:42 PM9/18/14
to rdev...@googlegroups.com
This issue should be fixed by https://github.com/hadley/testthat/pull/169 .

-Kirill
Reply all
Reply to author
Forward
0 new messages