Rails 第二个请求出现 WebMock 错误 try ::NetConnectNotAllowedError
Rails WebMock error on the second request try ::NetConnectNotAllowedError
我想模拟自定义设计策略以在我的功能规范中对用户进行身份验证。为了存根对第 3 方应用程序的请求,我使用 WebMock 实现如下:
spec/utility/stub_methods.rb
def stub_aware_auth(creds, returns_token, _valid)
stub_request(:post, "http://example.com/oauth/token").
with(body: {"grant_type" => "password", "password" => creds.password, "username" => creds.email},
headers: {'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/x-www-form-urlencoded'}).
to_return(status: 200, body: {'access_token' => returns_token, 'token_type' => 'bearer', 'expires_in' => 1200}.to_json, headers: {})
end
在规范中被称为:
context 'AWARxE authenticated user' do
before do
stub_aware_auth(creds, return_token, valid)
end
let(:creds) do
OpenStruct.new(email: 'physiciansreallyshouldonlyautoauth@example.com', password: "Ican'tb3li3v3itsn0tbutt3r")
end
let(:return_token) { SecureRandom.hex(32) }
let(:valid) { true }
# other logic (...)
end
spec_helper.rb
WebMock.disable_net_connect!(allow_localhost: true)
它的工作方式非常令人惊讶,因为如果在一个测试示例中它必须使用 stub_aware_auth
两次,第一次请求 returns 定义的结果,但第二次会抛出错误:
WebMock::NetConnectNotAllowedError: Real HTTP connections are disabled. Unregistered request: POST http://example.com/oauth/token with body 'grant_type=password&password=Ican%27tb3li3v3itsn0tbutt3r&username=PHYSICIANSREALLYSHOULDONLYAUTOAUTH%40EXAMPLE.COM' with headers {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type'=>'application/x-www-form-urlencoded', 'User-Agent'=>'Faraday v0.12.1'}
You can stub this request with the following snippet:
stub_request(:post, "http://example.com/oauth/token").
with(body: {"grant_type"=>"password", "password"=>"Ican'tb3li3v3itsn0tbutt3r", "username"=>"PHYSICIANSREALLYSHOULDONLYAUTOAUTH@EXAMPLE.COM"},
headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type'=>'application/x-www-form-urlencoded', 'User-Agent'=>'Faraday v0.12.1'}).
to_return(status: 200, body: "", headers: {})
registered request stubs:
stub_request(:get, "http://example.com/api/v1/user").
with(headers: {'Authorization'=>'Bearer dc2dcf4c5b47ffcfea28c26490ed2a0e2580f152dfb18dbfc97670028d24ecaa'})
stub_request(:post, "http://example.com/oauth/token").
with(body: {"grant_type"=>"password", "password"=>"Ican'tb3li3v3itsn0tbutt3r", "username"=>"physiciansreallyshouldonlyautoauth@example.com"},
headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type'=>'application/x-www-form-urlencoded'})
这令人惊讶,因为 WebMock.disable_net_connect!(allow_localhost: true)
是在 spec_helper 中定义的。
[编辑]
如果有帮助,完整的失败示例:
spec/features/login_strategies_spec.rb
context 'AWARxE authenticated user' do
before do
stub_aware_auth(creds, return_token, valid)
end
let(:return_token) { SecureRandom.hex(32) }
let(:valid) { true }
context 'physician' do
let(:creds) do
OpenStruct.new(email: 'physiciansreallyshouldonlyautoauth@example.com', password: "Ican'tb3li3v3itsn0tbutt3r")
end
let(:user) { build(:physician) }
before do
stub_aware_user_info(user, 'Physician (MD, DO)', return_token, valid, 1)
end
# some other it block (...)
context 'case insensitive' do
let(:valid) { true }
let(:uppercase_email_creds) {
OpenStruct.new(email: creds.email.upcase, password: creds.password)
}
scenario 'logging in with upper case email' do
expect { subject }.to change(Login, :count)
logout
expect {
login(uppercase_email_creds)
}.to_not change(Login, :count)
expect(page).to have_current_path(name_search_registrants_url, url: true)
end
end
end
您正在创建的存根仍在带有小写电子邮件的原始 creds
上。除非您实际调用
之类的东西,否则 webmock 不可能模拟调用
stub_aware_auth(uppercase_email_creds, return_token, valid)
如果您实际上希望应用程序在正文中使用小写电子邮件进行调出,那么测试将失败,因为它应该会失败,它会使用大写电子邮件进行调出:
You can stub this request with the following snippet:
stub_request(:post, "http://example.com/oauth/token").
with(body: {..., "username"=>"PHYSICIANSREALLYSHOULDONLYAUTOAUTH@EXAMPLE.COM"},
...).
to_return(status: 200, body: "", headers: {})
我想模拟自定义设计策略以在我的功能规范中对用户进行身份验证。为了存根对第 3 方应用程序的请求,我使用 WebMock 实现如下:
spec/utility/stub_methods.rb
def stub_aware_auth(creds, returns_token, _valid)
stub_request(:post, "http://example.com/oauth/token").
with(body: {"grant_type" => "password", "password" => creds.password, "username" => creds.email},
headers: {'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/x-www-form-urlencoded'}).
to_return(status: 200, body: {'access_token' => returns_token, 'token_type' => 'bearer', 'expires_in' => 1200}.to_json, headers: {})
end
在规范中被称为:
context 'AWARxE authenticated user' do
before do
stub_aware_auth(creds, return_token, valid)
end
let(:creds) do
OpenStruct.new(email: 'physiciansreallyshouldonlyautoauth@example.com', password: "Ican'tb3li3v3itsn0tbutt3r")
end
let(:return_token) { SecureRandom.hex(32) }
let(:valid) { true }
# other logic (...)
end
spec_helper.rb
WebMock.disable_net_connect!(allow_localhost: true)
它的工作方式非常令人惊讶,因为如果在一个测试示例中它必须使用 stub_aware_auth
两次,第一次请求 returns 定义的结果,但第二次会抛出错误:
WebMock::NetConnectNotAllowedError: Real HTTP connections are disabled. Unregistered request: POST http://example.com/oauth/token with body 'grant_type=password&password=Ican%27tb3li3v3itsn0tbutt3r&username=PHYSICIANSREALLYSHOULDONLYAUTOAUTH%40EXAMPLE.COM' with headers {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type'=>'application/x-www-form-urlencoded', 'User-Agent'=>'Faraday v0.12.1'}
You can stub this request with the following snippet:
stub_request(:post, "http://example.com/oauth/token").
with(body: {"grant_type"=>"password", "password"=>"Ican'tb3li3v3itsn0tbutt3r", "username"=>"PHYSICIANSREALLYSHOULDONLYAUTOAUTH@EXAMPLE.COM"},
headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type'=>'application/x-www-form-urlencoded', 'User-Agent'=>'Faraday v0.12.1'}).
to_return(status: 200, body: "", headers: {})
registered request stubs:
stub_request(:get, "http://example.com/api/v1/user").
with(headers: {'Authorization'=>'Bearer dc2dcf4c5b47ffcfea28c26490ed2a0e2580f152dfb18dbfc97670028d24ecaa'})
stub_request(:post, "http://example.com/oauth/token").
with(body: {"grant_type"=>"password", "password"=>"Ican'tb3li3v3itsn0tbutt3r", "username"=>"physiciansreallyshouldonlyautoauth@example.com"},
headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type'=>'application/x-www-form-urlencoded'})
这令人惊讶,因为 WebMock.disable_net_connect!(allow_localhost: true)
是在 spec_helper 中定义的。
[编辑]
如果有帮助,完整的失败示例:
spec/features/login_strategies_spec.rb
context 'AWARxE authenticated user' do
before do
stub_aware_auth(creds, return_token, valid)
end
let(:return_token) { SecureRandom.hex(32) }
let(:valid) { true }
context 'physician' do
let(:creds) do
OpenStruct.new(email: 'physiciansreallyshouldonlyautoauth@example.com', password: "Ican'tb3li3v3itsn0tbutt3r")
end
let(:user) { build(:physician) }
before do
stub_aware_user_info(user, 'Physician (MD, DO)', return_token, valid, 1)
end
# some other it block (...)
context 'case insensitive' do
let(:valid) { true }
let(:uppercase_email_creds) {
OpenStruct.new(email: creds.email.upcase, password: creds.password)
}
scenario 'logging in with upper case email' do
expect { subject }.to change(Login, :count)
logout
expect {
login(uppercase_email_creds)
}.to_not change(Login, :count)
expect(page).to have_current_path(name_search_registrants_url, url: true)
end
end
end
您正在创建的存根仍在带有小写电子邮件的原始 creds
上。除非您实际调用
stub_aware_auth(uppercase_email_creds, return_token, valid)
如果您实际上希望应用程序在正文中使用小写电子邮件进行调出,那么测试将失败,因为它应该会失败,它会使用大写电子邮件进行调出:
You can stub this request with the following snippet:
stub_request(:post, "http://example.com/oauth/token").
with(body: {..., "username"=>"PHYSICIANSREALLYSHOULDONLYAUTOAUTH@EXAMPLE.COM"},
...).
to_return(status: 200, body: "", headers: {})