VCR 说 "no cassette in use" 即使在指定磁带之后
VCR says "no cassette in use" even after specifying cassette
我有一个 api-only RoR 应用程序和用户模型。用户通过 Twilio/Authy 进行身份验证(使用 this gem)。每个用户 has_one
authy_user
存储授权信息的模型,dependent: :destroy
。
authy_user
模型有一个 before_destroy
挂钩,它通过 authy gem 连接到 authy api 并删除那里的用户。
authy_user
规格 运行 很好,而且我已经为两个 registering and deleting 用户录制了带有授权 api.
的磁带
authy_user
规范的一部分:
describe "delete user" do
before do
@user = create(:user_with_authy_user)
end
context "user is registered" do
it "deletes user in authy and locally" do
VCR.use_cassette("authy_delete_user") do
expect {
@user.authy_user.destroy
}.to change { AuthyUser.count }.by(-1)
end
end
end
end
(如果我将其从 @user.authy_user.destroy
更改为 @user.destroy
,则会失败并出现与下面相同的错误)
我的问题是 user
请求规范,特别是删除用户的规范。
这是失败的规范:
describe "DELETE /user" do
context "user exists" do
before do
@user = create(:user_with_authy_user)
@token = JWTService.issue_access_token user: @user, provider: "authy"
end
it "deletes the user" do
expect {
VCR.use_cassette("authy_delete_user") do
delete(user_path, headers: { "X-Auth-Token": @token })
end
}.to change { User.count }.by(-1)
expect(status).to eq(204)
expect(body).to be_blank
end
end
end
这是失败的原因:
1) Users DELETE /user user exists deletes the user
Failure/Error: Authy::API.delete_user id: authy_id
VCR::Errors::UnhandledHTTPRequestError:
================================================================================
An HTTP request has been made that VCR does not know how to handle:
POST https://api.authy.com/protected/json/users/delete/92962960
There is currently no cassette in use. There are a few ways
you can configure VCR to handle this request:
* If you're surprised VCR is raising this error
and want insight about how VCR attempted to handle the request,
you can use the debug_logger configuration option to log more details [1].
* If you want VCR to record this request and play it back during future test
runs, you should wrap your test (or this portion of your test) in a
`VCR.use_cassette` block [2].
* If you only want VCR to handle requests made while a cassette is in use,
configure `allow_http_connections_when_no_cassette = true`. VCR will
ignore this request since it is made when there is no cassette [3].
* If you want VCR to ignore this request (and others like it), you can
set an `ignore_request` callback [4].
[1] https://www.relishapp.com/vcr/vcr/v/4-0-0/docs/configuration/debug-logging
[2] https://www.relishapp.com/vcr/vcr/v/4-0-0/docs/getting-started
[3] https://www.relishapp.com/vcr/vcr/v/4-0-0/docs/configuration/allow-http-connections-when-no-cassette
[4] https://www.relishapp.com/vcr/vcr/v/4-0-0/docs/configuration/ignore-request
================================================================================
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/vcr-4.0.0/lib/vcr/request_handler.rb:97:in `on_unhandled_request'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/vcr-4.0.0/lib/vcr/library_hooks/webmock.rb:129:in `on_unhandled_request'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/vcr-4.0.0/lib/vcr/request_handler.rb:24:in `handle'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/vcr-4.0.0/lib/vcr/library_hooks/webmock.rb:144:in `block in <module:WebMock>'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/webmock-3.4.2/lib/webmock/stub_registry.rb:28:in `block in register_global_stub'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/webmock-3.4.2/lib/webmock/request_pattern.rb:40:in `matches?'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/webmock-3.4.2/lib/webmock/stub_registry.rb:58:in `block in request_stub_for'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/webmock-3.4.2/lib/webmock/stub_registry.rb:57:in `each'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/webmock-3.4.2/lib/webmock/stub_registry.rb:57:in `detect'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/webmock-3.4.2/lib/webmock/stub_registry.rb:57:in `request_stub_for'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/webmock-3.4.2/lib/webmock/stub_registry.rb:50:in `response_for_request'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/webmock-3.4.2/lib/webmock/http_lib_adapters/httpclient_adapter.rb:187:in `block in webmock_responses'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/webmock-3.4.2/lib/webmock/http_lib_adapters/httpclient_adapter.rb:59:in `do_get'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/webmock-3.4.2/lib/webmock/http_lib_adapters/httpclient_adapter.rb:47:in `do_get_block'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/httpclient-2.8.3/lib/httpclient.rb:1019:in `block in do_request'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/httpclient-2.8.3/lib/httpclient.rb:1133:in `protect_keep_alive_disconnected'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/httpclient-2.8.3/lib/httpclient.rb:1014:in `do_request'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/httpclient-2.8.3/lib/httpclient.rb:856:in `request'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/httpclient-2.8.3/lib/httpclient.rb:765:in `post'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/authy-2.7.4/lib/authy/api.rb:119:in `post_request'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/authy-2.7.4/lib/authy/api.rb:100:in `delete_user'
# ./app/services/authy_service.rb:20:in `delete'
# ./app/models/authy_user.rb:74:in `remove_from_authy'
# ./app/controllers/users_controller.rb:31:in `destroy'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/rack-2.0.5/lib/rack/etag.rb:25:in `call'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/rack-2.0.5/lib/rack/conditional_get.rb:38:in `call'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/rack-2.0.5/lib/rack/head.rb:12:in `call'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/railties-5.2.0/lib/rails/rack/logger.rb:38:in `call_app'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/railties-5.2.0/lib/rails/rack/logger.rb:26:in `block in call'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/railties-5.2.0/lib/rails/rack/logger.rb:26:in `call'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/rack-2.0.5/lib/rack/runtime.rb:22:in `call'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/rack-2.0.5/lib/rack/sendfile.rb:111:in `call'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/railties-5.2.0/lib/rails/engine.rb:524:in `call'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/rack-test-1.0.0/lib/rack/mock_session.rb:29:in `request'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/rack-test-1.0.0/lib/rack/test.rb:259:in `process_request'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/rack-test-1.0.0/lib/rack/test.rb:119:in `request'
# ./spec/requests/users_request_spec.rb:137:in `block (5 levels) in <main>'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/vcr-4.0.0/lib/vcr/util/variable_args_block_caller.rb:9:in `call_block'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/vcr-4.0.0/lib/vcr.rb:188:in `use_cassette'
# ./spec/requests/users_request_spec.rb:136:in `block (4 levels) in <main>'
看起来 use_cassette
被调用了,但也许它在路上的某个地方被取消了?
跟user
和authy_user
的dependent: :destroy
关系有关系吗?
感谢任何帮助,如果您需要更多信息,请告诉我。
也许,请求中的某些内容在您每次执行时都会发生变化,例如 HTTP header、时间戳,并且由于您没有指定 VCR 来记录新事务,因此它将失败。
我会调试它,使用
VCR.use_cassette("authy_delete_user", record: :new_episodes)
看看是否记录了一个新的磁带并比较两者,看看输出,看看有什么变化。
默认情况下,如果请求中的任何内容发生变化,就会写入新的磁带或抛出错误(您的情况)。在这种情况下,您可以指定磁带数据和请求的匹配方式,例如使用 match_requests_on
,请参阅 here
我有一个 api-only RoR 应用程序和用户模型。用户通过 Twilio/Authy 进行身份验证(使用 this gem)。每个用户 has_one
authy_user
存储授权信息的模型,dependent: :destroy
。
authy_user
模型有一个 before_destroy
挂钩,它通过 authy gem 连接到 authy api 并删除那里的用户。
authy_user
规格 运行 很好,而且我已经为两个 registering and deleting 用户录制了带有授权 api.
authy_user
规范的一部分:
describe "delete user" do
before do
@user = create(:user_with_authy_user)
end
context "user is registered" do
it "deletes user in authy and locally" do
VCR.use_cassette("authy_delete_user") do
expect {
@user.authy_user.destroy
}.to change { AuthyUser.count }.by(-1)
end
end
end
end
(如果我将其从 @user.authy_user.destroy
更改为 @user.destroy
,则会失败并出现与下面相同的错误)
我的问题是 user
请求规范,特别是删除用户的规范。
这是失败的规范:
describe "DELETE /user" do
context "user exists" do
before do
@user = create(:user_with_authy_user)
@token = JWTService.issue_access_token user: @user, provider: "authy"
end
it "deletes the user" do
expect {
VCR.use_cassette("authy_delete_user") do
delete(user_path, headers: { "X-Auth-Token": @token })
end
}.to change { User.count }.by(-1)
expect(status).to eq(204)
expect(body).to be_blank
end
end
end
这是失败的原因:
1) Users DELETE /user user exists deletes the user
Failure/Error: Authy::API.delete_user id: authy_id
VCR::Errors::UnhandledHTTPRequestError:
================================================================================
An HTTP request has been made that VCR does not know how to handle:
POST https://api.authy.com/protected/json/users/delete/92962960
There is currently no cassette in use. There are a few ways
you can configure VCR to handle this request:
* If you're surprised VCR is raising this error
and want insight about how VCR attempted to handle the request,
you can use the debug_logger configuration option to log more details [1].
* If you want VCR to record this request and play it back during future test
runs, you should wrap your test (or this portion of your test) in a
`VCR.use_cassette` block [2].
* If you only want VCR to handle requests made while a cassette is in use,
configure `allow_http_connections_when_no_cassette = true`. VCR will
ignore this request since it is made when there is no cassette [3].
* If you want VCR to ignore this request (and others like it), you can
set an `ignore_request` callback [4].
[1] https://www.relishapp.com/vcr/vcr/v/4-0-0/docs/configuration/debug-logging
[2] https://www.relishapp.com/vcr/vcr/v/4-0-0/docs/getting-started
[3] https://www.relishapp.com/vcr/vcr/v/4-0-0/docs/configuration/allow-http-connections-when-no-cassette
[4] https://www.relishapp.com/vcr/vcr/v/4-0-0/docs/configuration/ignore-request
================================================================================
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/vcr-4.0.0/lib/vcr/request_handler.rb:97:in `on_unhandled_request'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/vcr-4.0.0/lib/vcr/library_hooks/webmock.rb:129:in `on_unhandled_request'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/vcr-4.0.0/lib/vcr/request_handler.rb:24:in `handle'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/vcr-4.0.0/lib/vcr/library_hooks/webmock.rb:144:in `block in <module:WebMock>'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/webmock-3.4.2/lib/webmock/stub_registry.rb:28:in `block in register_global_stub'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/webmock-3.4.2/lib/webmock/request_pattern.rb:40:in `matches?'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/webmock-3.4.2/lib/webmock/stub_registry.rb:58:in `block in request_stub_for'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/webmock-3.4.2/lib/webmock/stub_registry.rb:57:in `each'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/webmock-3.4.2/lib/webmock/stub_registry.rb:57:in `detect'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/webmock-3.4.2/lib/webmock/stub_registry.rb:57:in `request_stub_for'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/webmock-3.4.2/lib/webmock/stub_registry.rb:50:in `response_for_request'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/webmock-3.4.2/lib/webmock/http_lib_adapters/httpclient_adapter.rb:187:in `block in webmock_responses'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/webmock-3.4.2/lib/webmock/http_lib_adapters/httpclient_adapter.rb:59:in `do_get'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/webmock-3.4.2/lib/webmock/http_lib_adapters/httpclient_adapter.rb:47:in `do_get_block'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/httpclient-2.8.3/lib/httpclient.rb:1019:in `block in do_request'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/httpclient-2.8.3/lib/httpclient.rb:1133:in `protect_keep_alive_disconnected'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/httpclient-2.8.3/lib/httpclient.rb:1014:in `do_request'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/httpclient-2.8.3/lib/httpclient.rb:856:in `request'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/httpclient-2.8.3/lib/httpclient.rb:765:in `post'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/authy-2.7.4/lib/authy/api.rb:119:in `post_request'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/authy-2.7.4/lib/authy/api.rb:100:in `delete_user'
# ./app/services/authy_service.rb:20:in `delete'
# ./app/models/authy_user.rb:74:in `remove_from_authy'
# ./app/controllers/users_controller.rb:31:in `destroy'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/rack-2.0.5/lib/rack/etag.rb:25:in `call'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/rack-2.0.5/lib/rack/conditional_get.rb:38:in `call'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/rack-2.0.5/lib/rack/head.rb:12:in `call'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/railties-5.2.0/lib/rails/rack/logger.rb:38:in `call_app'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/railties-5.2.0/lib/rails/rack/logger.rb:26:in `block in call'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/railties-5.2.0/lib/rails/rack/logger.rb:26:in `call'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/rack-2.0.5/lib/rack/runtime.rb:22:in `call'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/rack-2.0.5/lib/rack/sendfile.rb:111:in `call'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/railties-5.2.0/lib/rails/engine.rb:524:in `call'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/rack-test-1.0.0/lib/rack/mock_session.rb:29:in `request'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/rack-test-1.0.0/lib/rack/test.rb:259:in `process_request'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/rack-test-1.0.0/lib/rack/test.rb:119:in `request'
# ./spec/requests/users_request_spec.rb:137:in `block (5 levels) in <main>'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/vcr-4.0.0/lib/vcr/util/variable_args_block_caller.rb:9:in `call_block'
# /Users/raymondgulbrandsen/.gem/ruby/2.5.0/gems/vcr-4.0.0/lib/vcr.rb:188:in `use_cassette'
# ./spec/requests/users_request_spec.rb:136:in `block (4 levels) in <main>'
看起来 use_cassette
被调用了,但也许它在路上的某个地方被取消了?
跟user
和authy_user
的dependent: :destroy
关系有关系吗?
感谢任何帮助,如果您需要更多信息,请告诉我。
也许,请求中的某些内容在您每次执行时都会发生变化,例如 HTTP header、时间戳,并且由于您没有指定 VCR 来记录新事务,因此它将失败。
我会调试它,使用
VCR.use_cassette("authy_delete_user", record: :new_episodes)
看看是否记录了一个新的磁带并比较两者,看看输出,看看有什么变化。
默认情况下,如果请求中的任何内容发生变化,就会写入新的磁带或抛出错误(您的情况)。在这种情况下,您可以指定磁带数据和请求的匹配方式,例如使用 match_requests_on
,请参阅 here