can't modify frozen String: ""
Hi,
There are following test failures:
Failures:
1) HTTP.rb with WebMock allows a response with multiple values for the same header to be recorded and played back exactly as-is
Failure/Error: webmock_response.body = body.to_s
FrozenError:
can't modify frozen String: ""
Shared Example Group: "complex cross-concern behaviors" called from ./spec/acceptance/webmock_shared.rb:39
Shared Example Group: "with WebMock" called from ./spec/acceptance/http_rb/http_rb_spec.rb:10
# ./lib/webmock/http_lib_adapters/http_rb/response.rb:7:in `to_webmock'
# ./lib/webmock/http_lib_adapters/http_rb/webmock.rb:52:in `perform'
# ./lib/webmock/http_lib_adapters/http_rb/webmock.rb:10:in `exec'
# ./lib/webmock/http_lib_adapters/http_rb/client.rb:7:in `perform'
# ./spec/acceptance/http_rb/http_rb_spec_helper.rb:14:in `http_request'
# ./spec/acceptance/shared/complex_cross_concern_behaviors.rb:7:in `block (2 levels) in <top (required)>'
2) HTTP.rb with WebMock when webmock is disabled should not register executed requests
Failure/Error: body: response.body.to_s,
FrozenError:
can't modify frozen String: ""
Shared Example Group: "disabled WebMock" called from ./spec/acceptance/shared/enabling_and_disabling_webmock.rb:9
Shared Example Group: "enabled and disabled webmock" called from ./spec/acceptance/webmock_shared.rb:37
Shared Example Group: "with WebMock" called from ./spec/acceptance/http_rb/http_rb_spec.rb:10
# ./spec/acceptance/http_rb/http_rb_spec_helper.rb:17:in `http_request'
# ./spec/acceptance/shared/enabling_and_disabling_webmock.rb:44:in `block (2 levels) in <top (required)>'
3) HTTP.rb with WebMock when webmock is disabled should not block unstubbed requests
Failure/Error:
expect {
http_request(:get, webmock_server_url)
}.not_to raise_error
expected no Exception, got #<FrozenError: can't modify frozen String: ""> with backtrace:
# ./spec/acceptance/http_rb/http_rb_spec_helper.rb:17:in `http_request'
# ./spec/acceptance/shared/enabling_and_disabling_webmock.rb:50:in `block (3 levels) in <top (required)>'
# ./spec/acceptance/shared/enabling_and_disabling_webmock.rb:49:in `block (2 levels) in <top (required)>'
Shared Example Group: "disabled WebMock" called from ./spec/acceptance/shared/enabling_and_disabling_webmock.rb:9
Shared Example Group: "enabled and disabled webmock" called from ./spec/acceptance/webmock_shared.rb:37
Shared Example Group: "with WebMock" called from ./spec/acceptance/http_rb/http_rb_spec.rb:10
# ./spec/acceptance/shared/enabling_and_disabling_webmock.rb:49:in `block (2 levels) in <top (required)>'
4) HTTP.rb with WebMock when webmock is disabled should return real response even if there are stubs
Failure/Error: body: response.body.to_s,
FrozenError:
can't modify frozen String: ""
Shared Example Group: "disabled WebMock" called from ./spec/acceptance/shared/enabling_and_disabling_webmock.rb:9
Shared Example Group: "enabled and disabled webmock" called from ./spec/acceptance/webmock_shared.rb:37
Shared Example Group: "with WebMock" called from ./spec/acceptance/http_rb/http_rb_spec.rb:10
# ./spec/acceptance/http_rb/http_rb_spec_helper.rb:17:in `http_request'
# ./spec/acceptance/shared/enabling_and_disabling_webmock.rb:56:in `block (2 levels) in <top (required)>'
5) HTTP.rb with WebMock when webmock is disabled should not invoke any callbacks
Failure/Error: body: response.body.to_s,
FrozenError:
can't modify frozen String: ""
Shared Example Group: "disabled WebMock" called from ./spec/acceptance/shared/enabling_and_disabling_webmock.rb:9
Shared Example Group: "enabled and disabled webmock" called from ./spec/acceptance/webmock_shared.rb:37
Shared Example Group: "with WebMock" called from ./spec/acceptance/http_rb/http_rb_spec.rb:10
# ./spec/acceptance/http_rb/http_rb_spec_helper.rb:17:in `http_request'
# ./spec/acceptance/shared/enabling_and_disabling_webmock.rb:64:in `block (2 levels) in <top (required)>'
6) HTTP.rb with WebMock when webmock is enabled again should register executed requests
Failure/Error: webmock_response.body = body.to_s
FrozenError:
can't modify frozen String: ""
Shared Example Group: "enabled WebMock" called from ./spec/acceptance/shared/enabling_and_disabling_webmock.rb:17
Shared Example Group: "enabled and disabled webmock" called from ./spec/acceptance/webmock_shared.rb:37
Shared Example Group: "with WebMock" called from ./spec/acceptance/http_rb/http_rb_spec.rb:10
# ./lib/webmock/http_lib_adapters/http_rb/response.rb:7:in `to_webmock'
# ./lib/webmock/http_lib_adapters/http_rb/webmock.rb:52:in `perform'
# ./lib/webmock/http_lib_adapters/http_rb/webmock.rb:10:in `exec'
# ./lib/webmock/http_lib_adapters/http_rb/client.rb:7:in `perform'
# ./spec/acceptance/http_rb/http_rb_spec_helper.rb:14:in `http_request'
# ./spec/acceptance/shared/enabling_and_disabling_webmock.rb:72:in `block (2 levels) in <top (required)>'
7) HTTP.rb with WebMock when webmock is enabled again should invoke callbacks
Failure/Error: webmock_response.body = body.to_s
FrozenError:
can't modify frozen String: ""
Shared Example Group: "enabled WebMock" called from ./spec/acceptance/shared/enabling_and_disabling_webmock.rb:17
Shared Example Group: "enabled and disabled webmock" called from ./spec/acceptance/webmock_shared.rb:37
Shared Example Group: "with WebMock" called from ./spec/acceptance/http_rb/http_rb_spec.rb:10
# ./lib/webmock/http_lib_adapters/http_rb/response.rb:7:in `to_webmock'
# ./lib/webmock/http_lib_adapters/http_rb/webmock.rb:52:in `perform'
# ./lib/webmock/http_lib_adapters/http_rb/webmock.rb:10:in `exec'
# ./lib/webmock/http_lib_adapters/http_rb/client.rb:7:in `perform'
# ./spec/acceptance/http_rb/http_rb_spec_helper.rb:14:in `http_request'
# ./spec/acceptance/shared/enabling_and_disabling_webmock.rb:92:in `block (2 levels) in <top (required)>'
8) HTTP.rb with WebMock when webmock is disabled except this lib should register executed requests
Failure/Error: webmock_response.body = body.to_s
FrozenError:
can't modify frozen String: ""
Shared Example Group: "enabled WebMock" called from ./spec/acceptance/shared/enabling_and_disabling_webmock.rb:27
Shared Example Group: "enabled and disabled webmock" called from ./spec/acceptance/webmock_shared.rb:37
Shared Example Group: "with WebMock" called from ./spec/acceptance/http_rb/http_rb_spec.rb:10
# ./lib/webmock/http_lib_adapters/http_rb/response.rb:7:in `to_webmock'
# ./lib/webmock/http_lib_adapters/http_rb/webmock.rb:52:in `perform'
# ./lib/webmock/http_lib_adapters/http_rb/webmock.rb:10:in `exec'
# ./lib/webmock/http_lib_adapters/http_rb/client.rb:7:in `perform'
# ./spec/acceptance/http_rb/http_rb_spec_helper.rb:14:in `http_request'
# ./spec/acceptance/shared/enabling_and_disabling_webmock.rb:72:in `block (2 levels) in <top (required)>'
9) HTTP.rb with WebMock when webmock is disabled except this lib should invoke callbacks
Failure/Error: webmock_response.body = body.to_s
FrozenError:
can't modify frozen String: ""
Shared Example Group: "enabled WebMock" called from ./spec/acceptance/shared/enabling_and_disabling_webmock.rb:27
Shared Example Group: "enabled and disabled webmock" called from ./spec/acceptance/webmock_shared.rb:37
Shared Example Group: "with WebMock" called from ./spec/acceptance/http_rb/http_rb_spec.rb:10
# ./lib/webmock/http_lib_adapters/http_rb/response.rb:7:in `to_webmock'
# ./lib/webmock/http_lib_adapters/http_rb/webmock.rb:52:in `perform'
# ./lib/webmock/http_lib_adapters/http_rb/webmock.rb:10:in `exec'
# ./lib/webmock/http_lib_adapters/http_rb/client.rb:7:in `perform'
# ./spec/acceptance/http_rb/http_rb_spec_helper.rb:14:in `http_request'
# ./spec/acceptance/shared/enabling_and_disabling_webmock.rb:92:in `block (2 levels) in <top (required)>'
10) HTTP.rb with WebMock when webmock is enabled except this lib should not register executed requests
Failure/Error: body: response.body.to_s,
FrozenError:
can't modify frozen String: ""
Shared Example Group: "disabled WebMock" called from ./spec/acceptance/shared/enabling_and_disabling_webmock.rb:38
Shared Example Group: "enabled and disabled webmock" called from ./spec/acceptance/webmock_shared.rb:37
Shared Example Group: "with WebMock" called from ./spec/acceptance/http_rb/http_rb_spec.rb:10
# ./spec/acceptance/http_rb/http_rb_spec_helper.rb:17:in `http_request'
# ./spec/acceptance/shared/enabling_and_disabling_webmock.rb:44:in `block (2 levels) in <top (required)>'
11) HTTP.rb with WebMock when webmock is enabled except this lib should not block unstubbed requests
Failure/Error:
expect {
http_request(:get, webmock_server_url)
}.not_to raise_error
expected no Exception, got #<FrozenError: can't modify frozen String: ""> with backtrace:
# ./spec/acceptance/http_rb/http_rb_spec_helper.rb:17:in `http_request'
# ./spec/acceptance/shared/enabling_and_disabling_webmock.rb:50:in `block (3 levels) in <top (required)>'
# ./spec/acceptance/shared/enabling_and_disabling_webmock.rb:49:in `block (2 levels) in <top (required)>'
Shared Example Group: "disabled WebMock" called from ./spec/acceptance/shared/enabling_and_disabling_webmock.rb:38
Shared Example Group: "enabled and disabled webmock" called from ./spec/acceptance/webmock_shared.rb:37
Shared Example Group: "with WebMock" called from ./spec/acceptance/http_rb/http_rb_spec.rb:10
# ./spec/acceptance/shared/enabling_and_disabling_webmock.rb:49:in `block (2 levels) in <top (required)>'
12) HTTP.rb with WebMock when webmock is enabled except this lib should return real response even if there are stubs
Failure/Error: body: response.body.to_s,
FrozenError:
can't modify frozen String: ""
Shared Example Group: "disabled WebMock" called from ./spec/acceptance/shared/enabling_and_disabling_webmock.rb:38
Shared Example Group: "enabled and disabled webmock" called from ./spec/acceptance/webmock_shared.rb:37
Shared Example Group: "with WebMock" called from ./spec/acceptance/http_rb/http_rb_spec.rb:10
# ./spec/acceptance/http_rb/http_rb_spec_helper.rb:17:in `http_request'
# ./spec/acceptance/shared/enabling_and_disabling_webmock.rb:56:in `block (2 levels) in <top (required)>'
13) HTTP.rb with WebMock when webmock is enabled except this lib should not invoke any callbacks
Failure/Error: body: response.body.to_s,
FrozenError:
can't modify frozen String: ""
Shared Example Group: "disabled WebMock" called from ./spec/acceptance/shared/enabling_and_disabling_webmock.rb:38
Shared Example Group: "enabled and disabled webmock" called from ./spec/acceptance/webmock_shared.rb:37
Shared Example Group: "with WebMock" called from ./spec/acceptance/http_rb/http_rb_spec.rb:10
# ./spec/acceptance/http_rb/http_rb_spec_helper.rb:17:in `http_request'
# ./spec/acceptance/shared/enabling_and_disabling_webmock.rb:64:in `block (2 levels) in <top (required)>'
Finished in 10.53 seconds (files took 2.18 seconds to load)
4028 examples, 13 failures
Failed examples:
rspec './spec/acceptance/http_rb/http_rb_spec.rb[1:1:14]' # HTTP.rb with WebMock allows a response with multiple values for the same header to be recorded and played back exactly as-is
rspec './spec/acceptance/http_rb/http_rb_spec.rb[1:1:10:1]' # HTTP.rb with WebMock when webmock is disabled should not register executed requests
rspec './spec/acceptance/http_rb/http_rb_spec.rb[1:1:10:2]' # HTTP.rb with WebMock when webmock is disabled should not block unstubbed requests
rspec './spec/acceptance/http_rb/http_rb_spec.rb[1:1:10:3]' # HTTP.rb with WebMock when webmock is disabled should return real response even if there are stubs
rspec './spec/acceptance/http_rb/http_rb_spec.rb[1:1:10:4]' # HTTP.rb with WebMock when webmock is disabled should not invoke any callbacks
rspec './spec/acceptance/http_rb/http_rb_spec.rb[1:1:11:1]' # HTTP.rb with WebMock when webmock is enabled again should register executed requests
rspec './spec/acceptance/http_rb/http_rb_spec.rb[1:1:11:4]' # HTTP.rb with WebMock when webmock is enabled again should invoke callbacks
rspec './spec/acceptance/http_rb/http_rb_spec.rb[1:1:12:1]' # HTTP.rb with WebMock when webmock is disabled except this lib should register executed requests
rspec './spec/acceptance/http_rb/http_rb_spec.rb[1:1:12:4]' # HTTP.rb with WebMock when webmock is disabled except this lib should invoke callbacks
rspec './spec/acceptance/http_rb/http_rb_spec.rb[1:1:13:1]' # HTTP.rb with WebMock when webmock is enabled except this lib should not register executed requests
rspec './spec/acceptance/http_rb/http_rb_spec.rb[1:1:13:2]' # HTTP.rb with WebMock when webmock is enabled except this lib should not block unstubbed requests
rspec './spec/acceptance/http_rb/http_rb_spec.rb[1:1:13:3]' # HTTP.rb with WebMock when webmock is enabled except this lib should return real response even if there are stubs
rspec './spec/acceptance/http_rb/http_rb_spec.rb[1:1:13:4]' # HTTP.rb with WebMock when webmock is enabled except this lib should not invoke any callbacks
Now, I am confused whether it is related to webmock or related to http?
@utkarsh2102 how can it be reproducted? what ruby version that is?
Let me guess. It started with ruby 2.7? In my library (a wrapper on Net::HTTP) I do:
response.body.tap{ |r| r.instance_variable_set :@last_response, response }
and once I stub the request as
.to_return status: 200
it falls with
in `instance_variable_set': can't modify frozen String: "" (FrozenError)
Haven't debugged it thoroughly but it feels like the stub returns a frozen string and it's not what real Net::HTTP does.
UPD: kludge fix: add , body: "" to the stubbing
Thank you for reporting, @utkarsh2102 and @Nakilon. I've addressed the issue by updating the response body to an empty, unfrozen string. This change will be included in the upcoming release.