Trouble stubbing 2nd-level function that uses double colon for third call
matthewcornell opened this issue · comments
Hi Folks. (Sorry if the title is confusing - I didn't know what exactly to put.) I'm new to R and to mockery. Thanks for your work. After a lot of experimentation I've discovered behavior that seems like a bug to me, but it's entirely possible I'm missing something basic. It revolves around mocking a second-level function that calls another package's function using the double colon syntax to specify the namespace. In this case I have failed to find a way to get stub()
to work. By accident I found I am able to stub the called function if I remove the namespace reference.
The following results are when there is no local development server running at :8000. "fails" means the function is not successfully mocked: GET is called but the connection is refused. "works" means GET is mocked, but then stop_for_status gets the expected error (I'm returning a string, not a proper response object).
I hope this is enough to demonstrate the problem I'm having. Thank you.
# file 1: connection.R
mockery_bug <- function() {
mockery_bug2()
}
mockery_bug2 <- function() {
# response <- httr::GET(url = "http://127.0.0.1:8000/") # namespace -> cannot get stub to work
response <- GET(url = "http://127.0.0.1:8000/") # no namespace -> am able to get stub to work
httr::stop_for_status(response)
}
# file 2: test_connection.R
test_that("mockery bug", {
# mockery::stub(mockery_bug2, 'httr::GET', "GET value", depth=2) # fails when mockery_bug2 calls `httr::GET`:
# -> fails to mock (GET gets called): Failed to connect to 127.0.0.1 port 8000: Connection refused
# mockery::stub(mockery_bug2, 'GET', "GET value", depth=2) # works when mockery_bug2 calls `GET`:
mockery::stub(mockery_bug2, 'GET', "GET value", depth=2) # works when mockery_bug2 calls `GET`:
# -> does mock (GET value is bad - as expected): no applicable method for 'status_code' applied to an object of class "character"
mockery_bug()
})
Hello,
Thanks for the note. Please change
mockery::stub(mockery_bug2, 'GET', "GET value", depth=2)
to
mockery::stub(mockery_bug, 'GET', "GET value", depth=2)
, and likewise for the namespaced call,
and let me know what happens.
You are calling mockery_bug
, so you should be stubbing in mockery_bug
. The depth=2 option should take care of ensuring the stub is active in all functions called from mockery_bug
. Your current implementation is stubbing GET
out when it is called from mockery_bug2
when mockery_bug2
that is called from the test function, not from mockery_bug
.
Thanks. If I understand your comment correctly, I get the same results - the actual GET is called:
test-connection.R:12: error: mockery bug
Failed to connect to 127.0.0.1 port 8000: Connection refused
mockery_bug <- function() {
mockery_bug2()
}
mockery_bug2 <- function() {
response <- httr::GET(url = "http://127.0.0.1:8000/")
httr::stop_for_status(response)
}
test_that("mockery bug", {
mockery::stub(mockery_bug, 'GET', "GET value", depth=2)
mockery_bug()
})
I see. In this case you are stubbing 'GET', but calling the namespaced version 'httr::GET'. Can you try the same thing with
mockery::stub(mockery_bug, 'httr::GET', "GET value", depth=2)
or otherwise call the non-namespaced version in bug2.
thanks
Sorry, I should have said that was the first thing I tried. Same result - see code below. So is this a bug? I would have expected the below code to stub correctly - you too? I will stay with my initial workaround (not using the package name), but ideally including package name would work. (I like the idea of making package calls explicit like that - thought I read that recommendation in an R style guide somewhere...)
test-connection.R:12: error: mockery bug
Failed to connect to 127.0.0.1 port 8000: Connection refused
mockery_bug <- function() {
mockery_bug2()
}
mockery_bug2 <- function() {
response <- httr::GET(url = "http://127.0.0.1:8000/")
httr::stop_for_status(response)
}
test_that("mockery bug", {
mockery::stub(mockery_bug, 'httr::GET', "GET value", depth=2)
mockery_bug()
})
Yep, looks like a bug. Sorry about that. I'll take a look in the near future.