I have a package that has a variable assigned to the package namespace on load, like so:
.onLoad <- function(libname, pkgname){
assign(".myvar",
"foo",
envir = parent.env(environment()))
}
In my package, I use the variable like so:
myfn <- function(){
print(.myvar)
}
Now, during testing I need to change the variable prior to running the test.
test_that("myfn works correctly", {
myvar_tmp <- .myvar
withr::defer(assign(".myvar", myvar_tmp , pos = "package:mypackage"))
assign(".myvar", "bar", pos = "package:mypackage")
expect_equal(myfn(), "bar")
})
When I run this test, however, I get:
── Failure (Line 6): myfn works correctly ──────────────────────────────────────
myfn() not equal to "bar".
1/1 mismatches
x[1]: "foo"
y[1]: "bar"
Clearly, I haven't updated .myvar
correctly and myfn
is still picking up the value set on load.
When I try to set the variable outside the test,
> assign(".myvar", "bar", pos = "package:mypackage")
> .myvar
# [1] "bar"
and this appears to be the package variable and not one in another namespace:
pryr::where(".myvar")
<environment: package:mypackage>
attr(,"name")
[1] "package:mypackage"
attr(,"path")
[1] "/home/user/Documents/mypackage"
But that said, when I call the function
> myfn()
#[1] "foo"
it doesn't use the new value, but rather the value specified on load.
Question: What is the correct way of updating a variable in the package namespace in this situation?
PS This is a toy example to demonstrate the principle, as the real use case is more complex. I realise that it's not clear why I'd want to change the variable in testing, but for the actual use case it's necessary.
The problem seems to have been with the format of the assign statements. Instead of
assign(".myvar", "bar", pos = "package:mypackage")
I used,
assign(".myvar", "bar", pos = asNamespace("mypackage"))
and this resolved the issue.