情况:使用Rspec,FactoryGirl和VCR测试rails应用程序.
每次创建用户时,都会通过Stripe的API创建关联的Stripe客户.在测试时,添加一个VCR.use_cassette或describe "...", vcr: {cassette_name: 'stripe-customer'} do ...每个涉及用户创建的规范都没有意义.我的实际解决方案如下:
RSpec.configure do |config|
config.around do |example|
VCR.use_cassette('stripe-customer') do |cassette|
example.run
end
end
end
Run Code Online (Sandbox Code Playgroud)
但这是不可持续的,因为每个http请求都会使用相同的盒式磁带,这当然非常糟糕.
问题:如何根据个人要求使用特定灯具(磁带),而无需为每个规格指定磁带?
我有类似的东西,伪代码:
stub_request(:post, "api.stripe.com/customers").with(File.read("cassettes/stripe-customer"))
Run Code Online (Sandbox Code Playgroud)
相关的代码片段(作为要点):
# user_observer.rb
class UserObserver < ActiveRecord::Observer
def after_create(user)
user.create_profile!
begin
customer = Stripe::Customer.create(
email: user.email,
plan: 'default'
)
user.stripe_customer_id = customer.id
user.save!
rescue Stripe::InvalidRequestError => e
raise e
end
end
end
# vcr.rb
require 'vcr'
VCR.configure do |config|
config.default_cassette_options = { record: :once, re_record_interval: 1.day …Run Code Online (Sandbox Code Playgroud) 我想https使用存根调用webmock。我们假设网关 url 为https://some_gateway.com。
做完后:
stub_request(:post, 'https://some_gateway.com').with(body: {})
Run Code Online (Sandbox Code Playgroud)
在规格中。
我使用 Net::HTTP 生成请求:
Net::HTTP.post_form(URI.parse('https://some_gateway.com'), {})
Run Code Online (Sandbox Code Playgroud)
我收到问题,因为 Webmock 期望https://some_gateway.com但收到添加了端口 433 的版本,所以:http://www.secure.fake-payment.com:443/gateway_prod所以看不到注册的存根。
我该如何处理这种行为?
作为一名先驱(仅供参考),我是一名崭露头角的开发人员。我正在尝试为 Ruby gem 的 http POST 方法编写测试。据我所知,当您存根 http 响应时,例如使用 Ruby WebMock gem,您基本上是在告诉它要发布什么,然后人为地告诉它要响应什么。例如,这是我要测试的代码:
## githubrepo.rb
module Githubrepo
include HTTParty
def self.create(attributes)
post = HTTParty.post(
'https://api.github.com/user/repos',
:headers => {
'User-Agent' => 'Githubrepo',
'Content-Type' => 'application/json',
'Accept' => 'application/json'
},
:basic_auth => {
:username => attributes[:username],
:password => attributes[:password]
},
:body => {
'name' => attributes[:repository],
'description' => attributes[:description]
}.to_json
)
Githubrepo.parse_response_from(post, attributes[:wants_ssh])
end
Run Code Online (Sandbox Code Playgroud)
当我编写以下内容时,我的 RSpec 测试失败:
Githubrepo.create(:repository => 'test', :username => 'test_user', :password => '1234')
因为它发出了真正的 HTTP 请求。它建议我执行以下操作:
stub_request(:post, "https://test_user:test_password@api.github.com/user/repos").
with(:body => …Run Code Online (Sandbox Code Playgroud) Ruby 1.9.3,RSpec 2.13.0,WebMock 1.17.4,Rails 3
我正在为公司应用编写测试.有问题的控制器显示客户已拨打电话的表格,并允许排序/过滤选项.
编辑测试失败,因为使用我当前的设置,路径不会呈现,因为recorder_server它未在本地运行,或者未正确设置.请帮忙.
A Errno::ECONNREFUSED occurred in recordings#index:
Connection refused - connect(2)
/usr/local/lib/ruby/1.9.1/net/http.rb:763:in `initialize'
-------------------------------
Request:
-------------------------------
* URL : http://www.recorder.example.com:8080/recorded_calls
* IP address: 127.0.0.1
* Parameters: {"controller"=>"recordings", "action"=>"index"}
* Rails root: /var/www/rails/<repository>
Run Code Online (Sandbox Code Playgroud)
到目前为止,这是我的规格.
require 'spec_helper'
include Helpers
feature 'Exercise recordings controller' do
include_context "shared admin context"
background do
canned_xml = File.open("spec/support/assets/canned_response.xml").read
stub_request(:post, "http://recorder.example.com:8080/recorder/index").
with(body: {"durations"=>["1"], "durations_greater_less"=>["gt"], "filter_from_day"=>"29", "filter_from_hour"=>"0", "filter_from_minute"=>"0", "filter_from_month"=>"12", "filter_from_year"=>"2014", …Run Code Online (Sandbox Code Playgroud) Octokit 响应属于Sawyer::Response类型
它们看起来像这样:
{:name=>"code.py",
:content => "some content"}
Run Code Online (Sandbox Code Playgroud)
我正在尝试像这样存根我的请求
reponse_body = {:content => "some content"}
stub_request(:any, /.*api.github.com\/repos\/my_repo\/(.*)\/code.py/).to_return(:status => 200, :body => response_body)
Run Code Online (Sandbox Code Playgroud)
在我的代码中,我然后调用 response.content,所以我希望能够从响应中获取内容。
我目前收到错误:'WebMock::Response::InvalidBody: must be one of: [Proc, IO, Pathname, String, Array]。'哈希'给出'。response_body 的正确格式是什么?如果我将其转换为 json,则无法对代码中的对象执行 response.content。
我有一个带有用户模型的仅限 api 的 RoR 应用程序。用户通过 Twilio/Authy(使用这个gem)进行身份验证。has_one authy_user用于存储认证信息的每个用户模型,带有dependent: :destroy.
该authy_user模型有一个before_destroy钩子,它通过 authy gem 连接到 authy api 并删除那里的用户。
该authy_user规范运行蛮好的,我录的磁带两种登记并删除与authy 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
Run Code Online (Sandbox Code Playgroud)
(这个失败,出现相同的错误,如果我从改变它下面@user.authy_user.destroy到@user.destroy)
我的问题是user …
在Sinatra测试中,env['SERVER_NAME']默认为www.example.com。如何将其设置为任意域?
水豚有.default_host方法,但不使用水豚。
或者,是否可以更改env [ DEFAULT_HOST]?
使用RSpec,Sinatra,WebMock。
编辑:添加env['SERVER_NAME'] = 'www.foo.com'到RSpec测试引发异常:
NameError: undefined local variable or method 'env' for #<RSpec::Core::ExampleGroup::Nested_1::Nested_1:0x007fe6ce3b5ff8>
我正在尝试编写一个WebMock基于测试用例来模拟调用 http API。为此,我将其包含webmock/rspec在我的spec_helper.rb文件中,并添加WebMock.disable_net_connect!(allow_localhost: true)了禁止通过 Web 进行的 http 请求。但是当我运行一个虚拟测试来检查 http 请求被阻止的天气时,我可以看到仍然发出了 http 请求。
spec_helper.rb 文件:
ENV["RAILS_ENV"] ||= 'test'
require 'rubygems'
require File.expand_path("../../config/environment", __FILE__)
require 'authlogic/test_case'
include Authlogic::TestCase
require 'rspec/rails'
require 'rspec/autorun'
require 'rspec/mocks'
require 'capybara/rspec'
require 'capybara/rails'
require "paperclip/matchers"
require 'vcr'
require 'webmock/rspec'
WebMock.disable_net_connect!
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
RSpec.configure do |config|
config.treat_symbols_as_metadata_keys_with_true_values = true
config.mock_with :rspec
config.use_transactional_fixtures = false
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.include Paperclip::Shoulda::Matchers
config.include FactoryGirl::Syntax::Methods
config.infer_base_class_for_anonymous_controllers = false
config.include Rails.application.routes.url_helpers
config.include Capybara::DSL …Run Code Online (Sandbox Code Playgroud) 我创建了一个发出 HTTParty get 请求的函数。它会引发我需要测试的自定义错误消息。我尝试在测试中使用 Webmock 来存根请求,但它引发了<Net::OpenTimeout>. 如果 url 是动态构造的,我如何存根 get 请求?
def function(a , b)
# some logic , dynamic url constructed
response = HTTParty.get(url, headers: {"Content-Type" =>
"application/json"})
if response.code != 200
raise CustomError.new <<~EOF
Error while fetching job details.
Response code: #{response.code}
Response body: #{response.body}
EOF
end
JSON.parse(response.body)
Run Code Online (Sandbox Code Playgroud)
为了测试
def test_function
WebMock.stub_request(:get, url).with(:headers => {'Content-
Type'=>'application/json'}).to_return(:status => 500)
# HTTParty.stub(get: fake_response)
err = assert_raises CustumError do
c.function(a , b)
end
Run Code Online (Sandbox Code Playgroud) 我正在研究Ruby on Rails gem,并且正在尝试使用webmock,因为我需要交互(并测试)不受我控制的外部API。
所以,这是其中的片段,before(:each)因为我在那儿存了个片段:
before do
uri = URI.join(client.class.base_uri, DataComApi::ApiURI.search_contact).to_s
stub_request(
:get,
uri
).with(
query: hash_including({
'pageSize' => 0,
'offset' => 0
})
).to_return(
body: FactoryGirl.build(
:data_com_search_contact_response,
totalHits: 0
).to_json
)
# DEBUG
require 'httparty'
HTTParty.get(
uri,
{
query: {
offset: 0,
pageSize: 0
}
}
)
end
Run Code Online (Sandbox Code Playgroud)
在这里,您可以看到rspec命令的控制台输出:
3) DataComApi::Client#search_contact returns instance of SearchContact
Failure/Error: HTTParty.get(
WebMock::NetConnectNotAllowedError:
Real HTTP connections are disabled. Unregistered request: GET https://www.jigsaw.com/rest/searchContact.json?offset=0&pageSize=0
You can stub this request with the following …Run Code Online (Sandbox Code Playgroud) 没有WebMock,此代码可以正常工作.
提出例外:
Paperclip::AdapterRegistry::NoHandlerError:
No handler found for #<URI::HTTP:0x007ff3852cefb8 URL:http://www.example.com/images/foo.jpg>
# ./spec/support/api_mock.rb:34:in `process_image_for'
Run Code Online (Sandbox Code Playgroud)
测试:
let( :image_url ) { 'http://www.example.com/images/foo.jpg' }
...
stub_request(:post, image_url)
.to_return(:status => 200, :body => File.read('spec/fixtures/image.jpg'), :headers => {})
...hit Sinatra app...
Run Code Online (Sandbox Code Playgroud)
api_mock.rb:
def self.process_image_for suggestion, params
if params[:image]
suggestion.image = URI.parse( params[:image] ) # line 34
suggestion.save!
end
end
Run Code Online (Sandbox Code Playgroud) 错误信息是这样的
WebMock::Response::InvalidBody:必须是以下之一:[Proc、IO、路径名、字符串、数组]。给出“哈希”
我正在使用下面的代码来测试谷歌库以获取控制器中的用户信息
stub_request(:get, "https://www.googleapis.com/userinfo/v2/me")
.to_return(
body: {email: "test@test.con", name: "Petros"},
headers: {"Content-Type"=> ["application/json","charset=UTF-8"]}
)
Run Code Online (Sandbox Code Playgroud)
这是控制器代码
service = auth_with_oauth2_service(calendar_account.get_token)
response = service.get_userinfo_v2
calendar_account.user_id = current_user.id
calendar_account.email = response.email
calendar_account.name = response.name
Run Code Online (Sandbox Code Playgroud)
auth_with_oauth2_service 包含这个
def auth_with_oauth2_service(access_token)
auth_client = AccessToken.new access_token
service = Google::Apis::Oauth2V2::Oauth2Service.new
service.client_options.application_name = "****"
service.authorization = auth_client
return service
end
Run Code Online (Sandbox Code Playgroud)
回复内容形式
#<Hurley::Response GET https://www.googleapis.com/userinfo/v2/me == 200 (377 bytes) 647ms>
Success - #<Google::Apis::Oauth2V2::Userinfoplus:0x007ff38df5e820
@email="****",
@family_name="Kyriakou",
@gender="male",
@given_name="Petros",
@id="",
@link="***",
@locale="en-GB",
@name="Petros Kyriakou",
@picture=
"***",
@verified_email=true>
Run Code Online (Sandbox Code Playgroud)
服务是谷歌的授权,然后请求我可以通过response.email和response.name访问的用户数据。
然而,由于 google gem 获取信息并从中创建哈希,我无法对字符串执行任何 …
我需要帮助使用 Faraday gem 来存根请求。我正在提出这个请求
URL='https://secure.snd.payu.com//pl/standard/user/oauth/authorize'.freeze
url_encoded = 'grant_type=client_credentials' \
+ "&client_id=#{ENV['client_id'}" \
+ "&client_secret=#{ENV['client_secret'}"
connection = Faraday.new do |con|
con.response :oj, content_type: /\bjson$/
con.adapter Faraday.default_adapter
end
connection.post(URL, url_encoded)
Run Code Online (Sandbox Code Playgroud)
哪个输出
#<Faraday::Response:0x00000000016ff620 @on_complete_callbacks=[], @env=#<Faraday::Env @method=:post @body={"access_token"=>"00a4e007-220b-4119-aae8-3cb93bb36066", "token_type"=>"bearer", "expires_in"=>43199, "grant_type"=>"client_credentials"} @url=#<URI::HTTPS https://secure.snd.payu.com/pl/standard/user/oauth/authorize> @request=#<Faraday::RequestOptions (empty)> @request_headers={"User-Agent"=>"Faraday v0.17.1"} @ssl=#<Faraday::SSLOptions verify=true> @response=#<Faraday::Response:0x00000000016ff620 ...> @response_headers={"set-cookie"=>"cookieFingerprint=70a4a8d1-7b05-4cb9-9d5c-5ad12e966586; Expires=Fri, 25-Dec-2020 09:31:02 GMT; Path=/; ; HttpOnly, payu_persistent=mobile_agent-false#; Expires=Sun, 20-Dec-2020 09:31:02 GMT; Path=/; ; HttpOnly", "correlation-id"=>"0A4DC804-62FD_AC11000F-0050_5E047DD5_8A0178-0015", "cache-control"=>"no-store, no-cache, no-store, must-revalidate", "pragma"=>"no-cache, no-cache", "content-type"=>"application/json;charset=UTF-8", "transfer-encoding"=>"chunked", "date"=>"Thu, 26 Dec 2019 09:31:01 GMT", "server"=>"Apache", "x-content-type-options"=>"nosniff", …Run Code Online (Sandbox Code Playgroud)