如何使 gem WebMock 与包含 [方括号] 的 json 一起工作?
How do I make the gem WebMock work with json that includes [square brackets]?
有问题的 Rails 应用在测试中使用 Rspec、Capybara 和 WebMock。
在一个测试场景中,此代码有效:
response = RestClient.post 'the.domain.com',
{
"dados": {
"head": {
"servico": "autenticacao",
"chave": ""
},
"data": {
"empresa": "my_name",
"login": "my_login",
"senha": "my_password"
}
}
}.to_json
RSpec.configure do |config|
config.before(:each) do
stub_request(:any, 'the.domain.com').
with( body: hash_including(
{"dados": {
"head": {
"servico": "autenticacao",
"chave": ""
},
"data": {
"empresa": "my_name",
"login": "my_login",
"senha": "my_paasword"
}
}}.to_json
) ).to_return(
status: 200,
body: {"dados": {"btms": {"chave": "returned_key"}}}.to_json,
headers: {}
)
end
end
但是在同一场景中,紧接着发生的这件事不会:
data = []
data << {
"cdg_tipo_transporte": "3"
}
response = RestClient.post 'the.domain.com',
{
"dados": {
"head": {
"servico": "reserva_salva_lote",
"chave": response["dados"]["btms"]["chave"]
},
"data": data
}
}.to_json
RSpec.configure do |config|
config.before(:each) do
data = []
data << {
"cdg_tipo_transporte": "3"
}
stub_request(:any, 'the.domain.com').
with( body: hash_including(
{"dados": {
"head": {
"servico": "reserva_salva_lote",
"chave": "returned_key"
},
"data": data
} }.to_json
) ).to_return(
status: 200,
body: {"Status?": "OK"}.to_json,
headers: {}
)
end
end
我得到的错误是关于如何禁用真正的 HTTP 连接,这是一个未注册的请求。我认为这意味着 Rails and/or WebMock 与 json 不匹配。
我调查了不同的事情并尝试了不同的事情。似乎方括号是问题所在。当我在没有它们的情况下构建几乎任何东西时,它都有效。当我把它们放回去时,代码又坏了。
在这种情况下如何使用方括号?我需要它们在那里,因为我要发布到的真实 API 需要这种格式。
顺便说一句,开发环境与实际 API 通信,代码工作正常。人体试验是完美的。只是自动测试一直失败!
更新
这是错误堆栈:
保存响应的变量说 <WebMock::NetConnectNotAllowedError: Real HTTP connections are disabled. Unregistered request:
然后显示请求、建议的存根(与我的相匹配)和已注册的存根。
在此之下,我得到:
#<ActionDispatch::Cookies::CookieOverflow: ActionDispatch::Cookies::CookieOverflow>
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/actionpack-5.1.6/lib/action_dispatch/middleware/cookies.rb:594:in `commit'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/actionpack-5.1.6/lib/action_dispatch/middleware/cookies.rb:465:in `[]='
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/actionpack-5.1.6/lib/action_dispatch/middleware/session/cookie_store.rb:117:in `set_cookie'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/session/abstract/id.rb:363:in `commit_session'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/session/abstract/id.rb:234:in `context'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/session/abstract/id.rb:226:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/actionpack-5.1.6/lib/action_dispatch/middleware/cookies.rb:613:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/actionpack-5.1.6/lib/action_dispatch/middleware/callbacks.rb:26:in `block in call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/activesupport-5.1.6/lib/active_support/callbacks.rb:97:in `run_callbacks'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/actionpack-5.1.6/lib/action_dispatch/middleware/callbacks.rb:24:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/actionpack-5.1.6/lib/action_dispatch/middleware/debug_exceptions.rb:59:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/actionpack-5.1.6/lib/action_dispatch/middleware/show_exceptions.rb:31:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/railties-5.1.6/lib/rails/rack/logger.rb:36:in `call_app'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/railties-5.1.6/lib/rails/rack/logger.rb:24:in `block in call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/activesupport-5.1.6/lib/active_support/tagged_logging.rb:69:in `block in tagged'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/activesupport-5.1.6/lib/active_support/tagged_logging.rb:26:in `tagged'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/activesupport-5.1.6/lib/active_support/tagged_logging.rb:69:in `tagged'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/railties-5.1.6/lib/rails/rack/logger.rb:24:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/actionpack-5.1.6/lib/action_dispatch/middleware/remote_ip.rb:79:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/actionpack-5.1.6/lib/action_dispatch/middleware/request_id.rb:25:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/method_override.rb:22:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/runtime.rb:22:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/activesupport-5.1.6/lib/active_support/cache/strategy/local_cache_middleware.rb:27:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/actionpack-5.1.6/lib/action_dispatch/middleware/executor.rb:12:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/actionpack-5.1.6/lib/action_dispatch/middleware/static.rb:125:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/sendfile.rb:111:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/railties-5.1.6/lib/rails/engine.rb:522:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/urlmap.rb:68:in `block in call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/urlmap.rb:53:in `each'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/urlmap.rb:53:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/capybara-3.2.1/lib/capybara/server/middleware.rb:44:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/puma-3.11.4/lib/puma/configuration.rb:225:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/puma-3.11.4/lib/puma/server.rb:632:in `handle_request'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/puma-3.11.4/lib/puma/server.rb:446:in `process_client'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/puma-3.11.4/lib/puma/server.rb:306:in `block in run'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/puma-3.11.4/lib/puma/thread_pool.rb:120:in `block in spawn_thread'
和
Failure/Error: raise CookieOverflow if options[:value].bytesize > MAX_COOKIE_SIZE
ActionDispatch::Cookies::CookieOverflow:
ActionDispatch::Cookies::CookieOverflow
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/session/abstract/id.rb:363:in `commit_session'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/session/abstract/id.rb:234:in `context'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/session/abstract/id.rb:226:in `call'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/railties-5.1.6/lib/rails/rack/logger.rb:36:in `call_app'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/railties-5.1.6/lib/rails/rack/logger.rb:24:in `block in call'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/railties-5.1.6/lib/rails/rack/logger.rb:24:in `call'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/method_override.rb:22:in `call'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/runtime.rb:22:in `call'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/sendfile.rb:111:in `call'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/railties-5.1.6/lib/rails/engine.rb:522:in `call'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/urlmap.rb:68:in `block in call'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/urlmap.rb:53:in `each'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/urlmap.rb:53:in `call'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/capybara-3.2.1/lib/capybara/server/middleware.rb:44:in `call'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/puma-3.11.4/lib/puma/configuration.rb:225:in `call'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/puma-3.11.4/lib/puma/server.rb:632:in `handle_request'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/puma-3.11.4/lib/puma/server.rb:446:in `process_client'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/puma-3.11.4/lib/puma/server.rb:306:in `block in run'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/puma-3.11.4/lib/puma/thread_pool.rb:120:in `block in spawn_thread'
hash_including
采用键名和键值对进行匹配,您将 {...}.to_json
传递给它,因此它将尝试匹配整个 json 值作为键。
您的第二个请求存根期望 dados.head.chave
等于 "1234abcd"
,但第一个存根 returns "returned_key"
在 response["dados"]["btms"]["chave"]
中,显然存根不匹配导致 WebMock::NetConnectNotAllowedError
.
有问题的 Rails 应用在测试中使用 Rspec、Capybara 和 WebMock。
在一个测试场景中,此代码有效:
response = RestClient.post 'the.domain.com',
{
"dados": {
"head": {
"servico": "autenticacao",
"chave": ""
},
"data": {
"empresa": "my_name",
"login": "my_login",
"senha": "my_password"
}
}
}.to_json
RSpec.configure do |config|
config.before(:each) do
stub_request(:any, 'the.domain.com').
with( body: hash_including(
{"dados": {
"head": {
"servico": "autenticacao",
"chave": ""
},
"data": {
"empresa": "my_name",
"login": "my_login",
"senha": "my_paasword"
}
}}.to_json
) ).to_return(
status: 200,
body: {"dados": {"btms": {"chave": "returned_key"}}}.to_json,
headers: {}
)
end
end
但是在同一场景中,紧接着发生的这件事不会:
data = []
data << {
"cdg_tipo_transporte": "3"
}
response = RestClient.post 'the.domain.com',
{
"dados": {
"head": {
"servico": "reserva_salva_lote",
"chave": response["dados"]["btms"]["chave"]
},
"data": data
}
}.to_json
RSpec.configure do |config|
config.before(:each) do
data = []
data << {
"cdg_tipo_transporte": "3"
}
stub_request(:any, 'the.domain.com').
with( body: hash_including(
{"dados": {
"head": {
"servico": "reserva_salva_lote",
"chave": "returned_key"
},
"data": data
} }.to_json
) ).to_return(
status: 200,
body: {"Status?": "OK"}.to_json,
headers: {}
)
end
end
我得到的错误是关于如何禁用真正的 HTTP 连接,这是一个未注册的请求。我认为这意味着 Rails and/or WebMock 与 json 不匹配。
我调查了不同的事情并尝试了不同的事情。似乎方括号是问题所在。当我在没有它们的情况下构建几乎任何东西时,它都有效。当我把它们放回去时,代码又坏了。
在这种情况下如何使用方括号?我需要它们在那里,因为我要发布到的真实 API 需要这种格式。
顺便说一句,开发环境与实际 API 通信,代码工作正常。人体试验是完美的。只是自动测试一直失败!
更新
这是错误堆栈:
保存响应的变量说 <WebMock::NetConnectNotAllowedError: Real HTTP connections are disabled. Unregistered request:
然后显示请求、建议的存根(与我的相匹配)和已注册的存根。
在此之下,我得到:
#<ActionDispatch::Cookies::CookieOverflow: ActionDispatch::Cookies::CookieOverflow>
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/actionpack-5.1.6/lib/action_dispatch/middleware/cookies.rb:594:in `commit'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/actionpack-5.1.6/lib/action_dispatch/middleware/cookies.rb:465:in `[]='
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/actionpack-5.1.6/lib/action_dispatch/middleware/session/cookie_store.rb:117:in `set_cookie'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/session/abstract/id.rb:363:in `commit_session'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/session/abstract/id.rb:234:in `context'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/session/abstract/id.rb:226:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/actionpack-5.1.6/lib/action_dispatch/middleware/cookies.rb:613:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/actionpack-5.1.6/lib/action_dispatch/middleware/callbacks.rb:26:in `block in call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/activesupport-5.1.6/lib/active_support/callbacks.rb:97:in `run_callbacks'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/actionpack-5.1.6/lib/action_dispatch/middleware/callbacks.rb:24:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/actionpack-5.1.6/lib/action_dispatch/middleware/debug_exceptions.rb:59:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/actionpack-5.1.6/lib/action_dispatch/middleware/show_exceptions.rb:31:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/railties-5.1.6/lib/rails/rack/logger.rb:36:in `call_app'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/railties-5.1.6/lib/rails/rack/logger.rb:24:in `block in call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/activesupport-5.1.6/lib/active_support/tagged_logging.rb:69:in `block in tagged'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/activesupport-5.1.6/lib/active_support/tagged_logging.rb:26:in `tagged'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/activesupport-5.1.6/lib/active_support/tagged_logging.rb:69:in `tagged'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/railties-5.1.6/lib/rails/rack/logger.rb:24:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/actionpack-5.1.6/lib/action_dispatch/middleware/remote_ip.rb:79:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/actionpack-5.1.6/lib/action_dispatch/middleware/request_id.rb:25:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/method_override.rb:22:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/runtime.rb:22:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/activesupport-5.1.6/lib/active_support/cache/strategy/local_cache_middleware.rb:27:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/actionpack-5.1.6/lib/action_dispatch/middleware/executor.rb:12:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/actionpack-5.1.6/lib/action_dispatch/middleware/static.rb:125:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/sendfile.rb:111:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/railties-5.1.6/lib/rails/engine.rb:522:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/urlmap.rb:68:in `block in call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/urlmap.rb:53:in `each'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/urlmap.rb:53:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/capybara-3.2.1/lib/capybara/server/middleware.rb:44:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/puma-3.11.4/lib/puma/configuration.rb:225:in `call'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/puma-3.11.4/lib/puma/server.rb:632:in `handle_request'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/puma-3.11.4/lib/puma/server.rb:446:in `process_client'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/puma-3.11.4/lib/puma/server.rb:306:in `block in run'
/Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/puma-3.11.4/lib/puma/thread_pool.rb:120:in `block in spawn_thread'
和
Failure/Error: raise CookieOverflow if options[:value].bytesize > MAX_COOKIE_SIZE
ActionDispatch::Cookies::CookieOverflow:
ActionDispatch::Cookies::CookieOverflow
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/session/abstract/id.rb:363:in `commit_session'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/session/abstract/id.rb:234:in `context'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/session/abstract/id.rb:226:in `call'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/railties-5.1.6/lib/rails/rack/logger.rb:36:in `call_app'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/railties-5.1.6/lib/rails/rack/logger.rb:24:in `block in call'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/railties-5.1.6/lib/rails/rack/logger.rb:24:in `call'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/method_override.rb:22:in `call'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/runtime.rb:22:in `call'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/sendfile.rb:111:in `call'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/railties-5.1.6/lib/rails/engine.rb:522:in `call'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/urlmap.rb:68:in `block in call'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/urlmap.rb:53:in `each'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/rack-2.0.5/lib/rack/urlmap.rb:53:in `call'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/capybara-3.2.1/lib/capybara/server/middleware.rb:44:in `call'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/puma-3.11.4/lib/puma/configuration.rb:225:in `call'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/puma-3.11.4/lib/puma/server.rb:632:in `handle_request'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/puma-3.11.4/lib/puma/server.rb:446:in `process_client'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/puma-3.11.4/lib/puma/server.rb:306:in `block in run'
# /Users/ViviPoit/.rvm/gems/ruby-2.3.7/gems/puma-3.11.4/lib/puma/thread_pool.rb:120:in `block in spawn_thread'
hash_including
采用键名和键值对进行匹配,您将 {...}.to_json
传递给它,因此它将尝试匹配整个 json 值作为键。
您的第二个请求存根期望 dados.head.chave
等于 "1234abcd"
,但第一个存根 returns "returned_key"
在 response["dados"]["btms"]["chave"]
中,显然存根不匹配导致 WebMock::NetConnectNotAllowedError
.