nealrichardson / httptest

A Test Environment for HTTP Requests in R
https://enpiar.com/r/httptest/
Other
79 stars 10 forks source link

with_mock_api() does not fully clean up (untrace) #66

Closed bitkid closed 1 year ago

bitkid commented 2 years ago

i have a test where i use httptest like this

test_that("check list parameter", { httptest::with_mock_api({ expect_error(testClient$getMatrixData(c(10)), regexp = "listOfMatrixNames needs to be a vector of strings") expect_error(testClient$getMatrixData(10), regexp = "listOfMatrixNames needs to be a vector of strings") expect_error(testClient$getMatrixData("10", 10), regexp = "repository needs to be a string") expect_error(testClient$getMatrixData("bla"), regexp = "POST.") expect_error(testClient$getMatrixData(c("bla", "blub")), regexp = "POST.") }) })

and that works fine. i have also tests where i do real http request but if they run together in the same R session the real connection tests start throwing exception like this.

Error in readBin(con, "raw", nbytes) : invalid connection

That happens when uploading files using httr::upload_file(). i have to restart the session to make the integration tests pass again.

I include library("httptest") in setup.R (which is used by both, integration tests and mock tests)

R version: 4.1.0 Httr: 1.4.2 Httptest: 4.1.0

my crazy wild guess: httr::POST is missing here? https://github.com/nealrichardson/httptest/blob/5048d8e88c3bcdafdfca56b52b4dd9d8578ea195/R/trace.R#L32

nealrichardson commented 2 years ago

It looks like with_mock_api() isn't properly cleaning up after itself:

> options(httptest.debug=TRUE)
> with_mock_api(1)
Tracing function "form_file" as seen from package "httr"
Tracing function "body_config" as seen from package "httr"
Tracing function "request_perform" as seen from package "httr"
Untracing function "request_perform" as seen from package "httr"
[1] 1

There should be the same number of "Untracing" as "Tracing".

You may be able to work around this by adding an explicit untrace(curl::form_file) and untrace(httr::body_config). Or if you're starting a new project, you could switch to httr2 and httptest2, which does not use trace() as aggressively and doesn't seem to have this issue:

> library(httptest2)
> options(httptest2.debug.trace=TRUE)
> with_mock_api(1)
Tracing function "req_body_apply" as seen from package "httr2"
Untracing function "req_body_apply" as seen from package "httr2"
[1] 1
PetoLau commented 2 years ago

@nealrichardson untrace(httr::body_config) is not working:

Error: 'body_config' is not an exported object from 'namespace:httr'

since body_config is private function in httr. I tried untrace(httr:::body_config), but again failing with:

Error in methods::.TraceWithMethods(httr:::body_config, where = <environment>,  : 
  could not find function "body_config"

please, do you have any clue how to fix it? I don't want change to httr2 bcs I have lot of things already in httr. Thanks

nealrichardson commented 1 year ago

mock_perform() adds tracing to several functions: https://github.com/nealrichardson/httptest/blob/master/R/trace.R#L19-L35

But stop_mocking() doesn't untrace them all: https://github.com/nealrichardson/httptest/blob/master/R/trace.R#L63-L66

So a PR to fix this would add the missing calls to safe_untrace() to stop_mocking().

kforner commented 1 year ago

was also hit by that. will try to do a PR...