webmock
Library for stubbing and setting expectations on HTTP requests in Ruby.
How to match a URL like:
http://www.example.com/foo/:id/bar
http://www.example.com/foo/1/bar
http://www.example.com/foo/999/bar
stub_request(:post, "www.example.com")
Source: (StackOverflow)
This is on Rails 4.0.11. I am writing a test using minitest and webmock for a worker that interacts with an API. I have two test cases (so far) in my test file. When I run both tests, the second one (the one with "success" in the title) fails. When I comment out the passing test (the one with "retry" in the title), the test case that was failing passes. It seems like the test cases are interfering with each other, but I don't see how.
(I've obfuscated company confidential data in these code examples. Hi boss!)
Here's the test:
require 'test_helper'
class FoocorpCheckStatusWorkerTest < ActiveSupport::TestCase
REQUEST_HEADERS = {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type'=>'text/xml', 'User-Agent'=>'Ruby'}
EXPECTED_BODY = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<POSBizServices xmlns=\"http://api.foocorp.com\">\n <POSBizServiceHeader>\n <userId>ABC</userId>\n <password>abc123</password>\n <clientId>123</clientId>\n <action>CHECKSTATUS</action>\n <responseFormat>XML</responseFormat>\n </POSBizServiceHeader>\n <request>\n <checkStatus>\n <ecpdId>123</ecpdId>\n <refNum>12345678</refNum>\n </checkStatus>\n </request>\n</POSBizServices>\n"
def sample_response_body(order_level_status_code: '', line_level_status_code: '')
return <<-SAMPLE_RESPONSE_BODY
<?xml version="1.0" encoding="UTF-8"?>
<POSBizServices xmlns="http://api.foocorp.com">
<POSBizServiceHeader>
<userId>ABC</userId>
<password>abc123</password>
<clientId>123</clientId>
<statusCode>#{order_level_status_code}</statusCode>
<statusDescription>2015-01-29 14:03:07 [QA13:MS_WSQA4_ONEPOS_01:01] : Request Processed Successfully</statusDescription>
<action>CHECKSTATUS</action>
<responseFormat>XML</responseFormat>
</POSBizServiceHeader>
<response>
<statusResponse>
<count>1</count>
<orderStatus>
<orderId>12345678</orderId>
<orderDate>01/27/2015</orderDate>
<stats>1,0</stats>
<aceOrderNo></aceOrderNo>
<locationCode></locationCode>
<lineInfoList>
<count>1</count>
<lineStatus>
<lineSeq>1</lineSeq>
<statusCode>#{line_level_status_code}</statusCode>
<statusDesc>No Status Yet.</statusDesc>
</lineStatus>
</lineInfoList>
</orderStatus>
</statusResponse>
</response>
</POSBizServices>
SAMPLE_RESPONSE_BODY
end
test "retry codes leave activity processor step in waiting state and activity in auto_processing state" do
activity_processor_step = activity_processor_steps(:vip_vm_password_reset_step)
activity = activity_processor_step.activity
FoocorpVipCheckStatusWorker::STATUS_CODE_MATRIX[:retry].each do |status_code_pair|
stub_request(:post, FOOCORP_VIP_CONFIG[:base_url]).
with(:body => /^.*$/,
:headers => REQUEST_HEADERS
).
to_return(:status => 200, :body => sample_response_body(order_level_status_code: status_code_pair.first, line_level_status_code: status_code_pair.last), :headers => {})
FoocorpVipCheckStatusWorker.new.perform
activity.reload
assert_equal("auto_processing", activity.state)
activity_processor_step.reload
assert_equal("waiting", activity_processor_step.state)
end
end
test "success codes complete activity and activity processor step" do
activity_processor_step = activity_processor_steps(:vip_vm_password_reset_step)
activity = activity_processor_step.activity
FoocorpVipCheckStatusWorker::STATUS_CODE_MATRIX[:success].each do |status_code_pair|
stub_request(:post, FOOCORP_VIP_CONFIG[:base_url]).
with(:body => /^.*$/,
:headers => REQUEST_HEADERS
).
to_return(:status => 200, :body => sample_response_body(order_level_status_code: status_code_pair.first, line_level_status_code: status_code_pair.last), :headers => {})
FoocorpVipCheckStatusWorker.new.perform
activity.reload
assert_equal("completed", activity.state)
activity_processor_step.reload
assert_equal("completed", activity_processor_step.state)
end
end
end
Here's the worker:
class FoocorpVipCheckStatusWorker
@queue = :short_running
# Foocorp VIP returns an order-level status code and description
# and a line-level status code and description. The comments describing
# the status codes in STATUS_CODE_MATRIX are from Foocorp's Docs.
#
# Array format for status codes is:
# ["(order-level status code)", "(line-level status code)"]
STATUS_CODE_MATRIX = {
:success => [
["00057", "00051"] # Request Processed Successfully
],
:retry => [
["00057", "00053"], # No Status Yet
["00057", "00054"], # Order processed successfully but activation is pending.
["00099", ""], # Unexpected error occurred during processing e.g. null pointer exception which causes thread to terminate.
["00059", ""], # Server time out occurred.
["10009", ""], # Back End call returned invalid agent data.
["10010", ""], # Application fails to load ECPD profile details.
["00058", "10013"], # Backend calls fails to load Billing information for account. It may be due to some internal issue.
["00058", "10032"], # Exception occurred in Bulk Service write
["00058", "10033"], # Error occurred in Bulk Service write for reassign
["00058", "10040"], # Sub Account create failed
["00058", "10144"] # UNABLE TO RETRIEVE CREDIT INFORMATION
]
}
def perform
ActivityProcessorStep.where(state: "waiting").where("vip_ref_num IS NOT NULL").each do |activity_processor_step|
client = Remote::Clients::FoocorpVipClient.new(
:params => {
:ecpd_id => activity_processor_step.activity.carrier_account.parent_account.api_access_id,
:vip_ref_num => activity_processor_step.vip_ref_num
}
)
response = client.check_status
#TODO: Remove debugging code
#binding.pry
order_status_code = response.first[:order_status_code]
order_status_desc = response.first[:order_status_desc]
line_status_code = response.last[:line_status_code]
line_status_desc = response.last[:line_status_desc]
status_codes = [order_status_code, line_status_code]
response_message = line_status_desc.present? ? line_status_desc : order_status_desc
response_message ||= "No status description given"
success = STATUS_CODE_MATRIX[:success].detect{ |codes_array| codes_array == [order_status_code, line_status_code]}.present?
retry_status_check = STATUS_CODE_MATRIX[:retry].detect{ |codes_array| codes_array == [order_status_code, line_status_code]}.present?
stale_request = retry_status_check && Time.now > (activity_processor_step.created_at + activity_processor_step.days_to_expire.days)
if success
activity_processor_step.update_activity_status('Complete', nil, nil, response_message)
elsif stale_request
activity_processor_step.update_activity_status('Failure', nil, nil, "Activity processor step expired.")
elsif !retry_status_check
activity_processor_step.update_activity_status('Failure', nil, nil, response_message)
end
end
end
end
Here's my terminal output:
Running both test cases:
me@domo-kun ~/my-project (feature_foocorp_check_status_worker=)$ be rake test TEST=test/workers/foocorp_check_status_worker_test.rb
Run options: --seed 58882
# Running tests:
.F
Fabulous tests in 2.009658s, 0.9952 tests/s, 11.4447 assertions/s.
1) Failure:
FoocorpCheckStatusWorkerTest#test_success_codes_complete_activity_and_activity_processor_step [/Users/steven/Development/my-company/my_company/test/workers/foocorp_check_status_worker_test.rb:86]:
Expected: "completed"
Actual: "auto_processing"
2 tests, 23 assertions, 1 failures, 0 errors, 0 skips
Commenting out the first ("retry") test case:
me@domo-kun ~/my-project (feature_foocorp_check_status_worker=)$ be rake test TEST=test/workers/foocorp_check_status_worker_test.rb
Run options: --seed 14937
# Running tests:
.
Fabulous tests in 3.474386s, 0.2878 tests/s, 0.5756 assertions/s.
1 tests, 2 assertions, 0 failures, 0 errors, 0 skips
When I run both tests together and use binding.pry
(commented out here) in the worker to examine the value of response
during the "success" test case (the one that fails), I get the following two results. I expect the same result (the second one) in both cases.
Running both test cases:
[1] pry(#<VerizonVipCheckStatusWorker>)> response
=> [{:order_status_code=>"00057",
:order_status_desc=>"",
:_summary=>{:order_status_code=>"00057", :order_status_desc=>""}},
{:line_status_code=>"00053",
:line_status_desc=>"No Status Yet.",
:_summary=>{}}]
Commenting out the first ("retry") test case:
[2] pry(#<VerizonVipCheckStatusWorker>)> response
=> [{:order_status_code=>"00057",
:order_status_desc=>"",
:_summary=>{:order_status_code=>"00057", :order_status_desc=>""}},
{:line_status_code=>"00051",
:line_status_desc=>"No Status Yet.",
:_summary=>{}}]
The value of response in that last example is what I would expect it to be during the first iteration of the "retry" test case, not during the "success" case.
I've tried moving what was in a setup method into the constants and sample_response_body
method you see here. I also tried adding this teardown method, but it didn't help:
def teardown
WebMock.reset!
end
I'm writing both the worker and the test from scratch, so it's entirely possible that I have a dumb syntax/logic errors somewhere. I apologize for what is probably an overly verbose question, but this really has me tearing my hair out. Your help is appreciated. Thanks.
Source: (StackOverflow)
I am building an API wrapper and am writing some tests for it and I have a couple of questions.
1) How do I write an assert
for calls where data doesn't exist? For example, looking up a member by id using the API but the user won't exist yet.
2) How do I write an assert
for testing PUT
and DELETE
requests?
I already have a grasp on testing GET
and POST
requests just not sure on the other 2 verbs.
Source: (StackOverflow)
Situation: testing a rails application using Rspec, FactoryGirl and VCR.
Every time a User is created, an associated Stripe customer is created through Stripe's API. While testing, it doesn't really makes sense to add a VCR.use_cassette
or describe "...", vcr: {cassette_name: 'stripe-customer'} do ...
to every spec where User creation is involved. My actual solution is the following:
RSpec.configure do |config|
config.around do |example|
VCR.use_cassette('stripe-customer') do |cassette|
example.run
end
end
end
But this isn't sustainable because the same cassette will be used for every http request, which of course is very bad.
Question: How can I use specific fixtures (cassettes) based on individual request, without specifying the cassette for every spec?
I have something like this in mind, pseudo-code:
stub_request(:post, "api.stripe.com/customers").with(File.read("cassettes/stripe-customer"))
Relevant pieces of code (as a gist):
# 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 }
config.cassette_library_dir = 'spec/fixtures/cassettes'
config.hook_into :webmock
config.configure_rspec_metadata!
end
# user_spec.rb
describe :InstanceMethods do
let(:user) { FactoryGirl.create(:user) }
describe "#flexible_name" do
it "returns the name when name is specified" do
user.profile.first_name = "Foo"
user.profile.last_name = "Bar"
user.flexible_name.should eq("Foo Bar")
end
end
end
Edit
I ended doing something like this:
VCR.configure do |vcr|
vcr.around_http_request do |request|
if request.uri =~ /api.stripe.com/
uri = URI(request.uri)
name = "#{[uri.host, uri.path, request.method].join('/')}"
VCR.use_cassette(name, &request)
elsif request.uri =~ /twitter.com/
VCR.use_cassette('twitter', &request)
else
end
end
end
Source: (StackOverflow)
I am building a Ruby command-line program that communicates with a web service. I am using Cucumber and Aruba to test the program. The problem is that I need to control the data returned from the web service; the program grabs a stream of user comments, so this can change frequently as new comments are added. I tried to mock the web service using WebMock, but this didn't work, since Aruba spins the command-line program off into a separate process that is unaffected by WebMock (so it still communicated with the real web service).
How can I test the output of this program using Cucumber?
Edit: The web service returns the stream as JSON data. I've captured a snapshot of data to use for testing; in a nutshell, I'm looking for a way to substitute my static data in place of an actual call to the web service.
Or, if there's a completely different way to accomplish this goal, I'm all ears.
Source: (StackOverflow)
I am trying to simulate unexpected behaviour from a web api, such as not finding the server and timeouts, using webmock.
What would be the best way to do this? All I can think of is to do something like this:
stubbed_request = stub_request(:get, "#{host}/api/something.json").
with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json', 'User-Agent'=>'Ruby'}).
to_return(:status => [500, "Internal Server Error"])
That should work for things like 404 etc., but how can I test timeouts, server not found/offline server, and no internet connection?
Source: (StackOverflow)
This code works fine without WebMock.
Raising an exception:
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'
Test:
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...
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
Source: (StackOverflow)
I'm creating a controller spec for the get_token part of an oauth2 authentication. At this point the user has authorized my app and I need to generate and save the token and other information. Rspec fails with a somewhat cryptic error.
Failure/Error: get :auth, { code: "auth_code", scope: "read_write" }
OAuth2::Error:
{:token_type=>"bearer",
:stripe_publishable_key=>"PUBLISHABLE_KEY",
:scope=>"read_write",
:livemode=>"false",
:stripe_user_id=>"USER_ID",
:refresh_token=>"REFRESH_TOKEN",
:access_token=>"ACCESS_TOKEN"}
Here's the controller code. Rspec says it fails on get_token.
require 'oauth2'
def auth
code = params[:code]
client = oauth_client
token_response = client.auth_code.get_token(code, params: { scope: 'read_write' })
token = token_response.token
And here's the test. The webmock should be intercepting get_token. It is the autogenerated webmock suggeted by rspec that I filled in the body with the appropriate request and response body.
before do
stub_request(:post, "https://connect.stripe.com/oauth/token").
with(:body => {"client_id"=>"CLIENT_ID",
"client_secret"=>"SOME_SECRET",
"code"=>"auth_code",
"grant_type"=>"authorization_code",
"params"=>{"scope"=>"read_write"}},
: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.9.0'}).
to_return(:status => 200,
:body => {token_type: "bearer",
stripe_publishable_key: "PUBLISHABLE_KEY",
scope: "read_write",
livemode: "false",
stripe_user_id: "USER_ID",
refresh_token: "REFRESH_TOKEN",
access_token: "ACCESS_TOKEN"},
:headers => {})
end
describe "#auth" do
it "creates a payment gateway" do
get :auth, { code: "auth_code", scope: "read_write"
end
end
This process already works in practice so at least the controller code is not to blame. What am I doing wrong?
Source: (StackOverflow)
Ruby 1.9.3, RSpec 2.13.0, WebMock 1.17.4, Rails 3
I am writing tests for a company app. The controller in question displays a table of a customer's placed calls, and allows for sort/filter options.
EDIT The test fails because with my current setup, the path does not render, because the recorder_server
is either not running locally, OR not setup correctly. Please help with this, too.
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>
- As a call is placed, its data joins an xml file, created by an external API, called Recorder
- The RecordingsController takes the xml file, and parses it into a hash.
- When you visit the associated path, you see the results of the hash -- a table of placed calls, their attributes, and parameters for sort/filter.
Here is my spec so far.
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", "filter_prefix"=>true, "filter_to_day"=>"29", "filter_to_hour"=>"23", "filter_to_minute"=>"59", "filter_to_month"=>"12", "filter_to_year"=>"2014"}, # "shared_session_id"=>"19f9a08807cc70c1bf41885956695bde"},
headers: {'Accept'=>'*/*', 'Content-Type'=>'application/x-www-form-urlencoded', 'User-Agent'=>'Ruby'}).
to_return(status: 200, body: canned_xml, headers: {})
uri = URI.parse("http://recorder.example.com:8080/recorder/index")
visit recorded_calls_path
end
scenario 'show index page with 1 xml result' do
#page.save_and_open_page
expect(title).to eq("Recorded Calls")
end
end
And here is the RecordingsController
class RecordingsController < ApplicationController
# before_filter options
def index
test_session_id = request.session_options[:id]
#Make request to recording app for xml of files
uri = URI.parse("http://#{Rails.application.config.recorder_server}:#{Rails.application.config.recorder_server_port}/recorder/index")
http = Net::HTTP.new(uri.host, uri.port)
xml_request = Net::HTTP::Post.new(uri.request_uri)
xml_request_data = Hash.new
# sorting params
xml_request_data[:shared_session_id] = request.session_options[:id]
xml_request.set_form_data(xml_request_data)
response = http.request(xml_request)
if response.class == Net::HTTPOK
@recordings_xml = XmlSimple.xml_in(response.body)
@recordings_sorted = @recordings_xml["Recording"].sort { |a,b| Time.parse("#{a["date"]} #{a["time"]}") <=> Time.parse("#{b["date"]} #{b["time"]}") } unless @recordings_xml["Recording"].nil?
else @recordings_xml = Hash.new
end
end
# other defs
end
Any and all advice is much appreciated. Thank you.
Source: (StackOverflow)
I'm working on a Ruby on Rails gem and I'm trying webmock because I need to interact (and test) an external API not under my control.
So, here is the snippet which is in before(:each)
because I was stubbing it there:
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
And here you can see the console output of rspec
command:
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 snippet:
stub_request(:get, "https://www.jigsaw.com/rest/searchContact.json?offset=0&pageSize=0").
to_return(:status => 200, :body => "", :headers => {})
registered request stubs:
stub_request(:get, "https://www.jigsaw.com/rest/searchContact.json with query params hash_including({"offset"=>0, "pageSize"=>0})")
============================================================
# ./spec/models/client_spec.rb:65:in `block (3 levels) in <top (r
If I remove the :query
key both on HTTParty.get
and in stub_request
, it works, but I need those query keys and values to test the API.
I tested even by replacing in stub_request
, uri
with /searchContact.json/
but had same issue.
Here you can find a GIST
Source: (StackOverflow)
I don't have much experience with stubbing and am having issues with requests to Braintree using webmock and braintree-rails.
spec/spec_helper.rb
RSpec.configure do |config|
config.include(ConnectionHelper)
config.before(:each) do
stub_request(:post, /.*braintree.*/).
with(braintree_hash).to_return(gzipped_response)
end
end
spec/support/connection_helper.rb
def gzipped_response
{
status: 200,
body: "\u001F\x8B\b\0:\x87GU\0\u0003\u0003\0\0\0\0\0\0\0\0\0",
headers: {}
}
end
def braintree_hash
{ :body => /.*/,
:headers => {'Accept'=>'application/xml', 'Content-Type'=>'application/xml',
'User-Agent'=>'Braintree Ruby Gem 2.42.0 (braintree-rails-1.4.0)',
'X-Apiversion'=>'4'}
}
end
Rspec error:
2) Content: when ordering content show page has relevant information
Failure/Error: click_button "Order"
Braintree::UnexpectedError:
expected a gzipped response
# ./app/classes/payment.rb:13:in `generate_token'
# ./app/controllers/posts_controller.rb:44:in `pay'
# ./spec/features/content_spec.rb:251:in `block (4 levels) in <top (required)>'
I'm trying to test the page, not the payments themselves, however when rendering the page a token needs to be retrieved first and so I'm getting this error.
How would I go about faking a gzipped response, or alternatively skip anything to do with Braintree requests in my tests?
app/controllers/posts_controller.rb
def pay
@post = Post.find(params[:id])
@client_token = Payment.new(current_user).generate_token
end
app/classes/payment.rb
class Payment
def initialize(customer)
@customer = customer
@customer_id = @customer.id
end
def generate_token
Braintree::ClientToken.generate(customer_id: @customer_id)
end
end
Source: (StackOverflow)
As a precursor FYI, I'm a budding developer. I'm trying to write a test for an http POST method for a Ruby gem. From what I can understand, when you stub an http response, for instance with the Ruby WebMock gem, you're basically telling it what to post and then artificially telling it what to respond with. For example, here is the code I'm trying to test:
## 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
My RSpec test fails when I write:
Githubrepo.create(:repository => 'test', :username => 'test_user', :password => '1234')
because it makes a real HTTP request. It recommends I do the following instead:
stub_request(:post, "https://test_user:test_password@api.github.com/user/repos").
with(:body => "{\"name\":\"test_repo\",\"description\":null}",
:headers => {'Accept'=>'application/json', 'Content-Type'=>'application/json', 'User-Agent'=>'Githubrepo'}).
to_return(:status => 200, :body => "", :headers => {})
But to me, this seems like it's pointless since it's basically telling what to send and what to respond with. I can edit the URL to say "https://bananas@git-banana.banana"
and the header
to say Content-type => 'Rumplestilskin'
and RSpec is ok with that. How am I supposed to integrate this into testing the functionality of the create
method I specified above? Or if anything, can somebody point me to a solid beginner guide or blog to help me with this question? The Ruby gem READMEs seem to assume the user knows a thing or two already about this and I don't.
Source: (StackOverflow)
I have been trying for a while to stub multipart requests using webmock and have not found a satisfying solution.
Ideally, I would like to stub the request as follow:
stub_request(:post, 'http://test.api.com').with(:body => { :file1 => File.new('filepath1'), file2 => File.new('filepath2') })
However, this does not seem to work and RSpec complains that the request has not been stubbed. The non-stubbed request is printed:
stub_request(:post, "http://test.api.com").
with(:body => "--785340\r\nContent-Disposition: form-data; name=\"file1\"; filename=\"filepath1\"\r\nContent-Type: text/plain\r\n\r\nhello\r\n--785340\r\nContent-Disposition: form-data; name=\"file2\"; filename=\"filepath2\"\r\nContent-Type: text/plain\r\n\r\nhello2\r\n--785340\r\n",
:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate', 'Content-Length'=>'664', 'Content-Type'=>'multipart/form-data; boundary=785340', 'User-Agent'=>'Ruby'}).
to_return(:status => 200, :body => "", :headers => {})
Of course, I can't really follow this suggestion because the boundaries are generated dynamically. Any idea how I could properly stub these requests?
Thanks!
Bruno
Source: (StackOverflow)
I have a Rails 3 background job (delayed_job) which sends a hipchat / Campfire message to their API and I want to check the response in my Cucumber feature. Is there a way to get the last HTTP response(s) which VCR have recorded?
The feature looks like this
@vcr
Scenario: Send hipchat message when task created
Given an hipchat_sample integration exists with app: app "teamway"
When I create an "ActionMailer::Error" task to "Teamway"
And all jobs are worked off # invoke Delayed::Worker.new.work_off
Then a hipchat message should be sent "ActionMailer::Error"
In my step definition I want to check the response body:
Then /^a hipchat message should be sent "(.*?)"$/ do |arg1|
# Like this:
# VCR::Response.body.should == arg1
end
VCR already records the request and response, but I do not know how to take them. I think of something similar to catching the emails sent with Pickle's steps. Does anybody have an idea how to do this?
I use rails 3.2.8, cucumber-rails 1.3 and vcr 2.2.4 (with webmock).
Best regards
Torsten
Source: (StackOverflow)
I have a problem, I can run a test that uses vcr on its own and it works, it creates the cassette and it uses that on the next test. Great.
The problem is when I run all my tests together this particular test fails, because webmock disables http connections, I have seen this example on the Github repo page that explains how to expect real and not stubbed requests
My question is how Do I say: Allow Http connections for requests UNLESS there is a cassette. It should also CREATE the cassette when HTTP connections are allowed.
The VCR Settings
require 'vcr'
VCR.configure do | c |
if !ARGV.first.nil?
c.default_cassette_options = { :record => :new_episodes, :erb => true }
c.filter_sensitive_data('<BLACKBIRD_API_KEY>') {YAML.load(File.read('config/application.yml'))['BLACKBIRD_API_KEY'].to_s}
c.filter_sensitive_data('<BLACKBIRD_API_URL>') {YAML.load(File.read('config/application.yml'))['BLACKBIRD_API_URL'].to_s}
c.debug_logger = File.open(ARGV.first, 'w')
c.cassette_library_dir = 'spec/vcr'
c.hook_into :webmock
end
end
the above if statement exists because not EVERY test creates a cassette. So we want them to run when a cassette isn't needed.
The Test
require 'spec_helper'
describe Xaaron::Publishers::Users do
context "publish created users" do
before(:each) do
Xaaron.configuration.reset
no_user_member_roles_relation
Xaaron.configuration.publish_to_black_bird = true
Xaaron.configuration.black_bird_api_url = YAML.load(File.read('config/application.yml'))['BLACKBIRD_API_URL']
Xaaron.configuration.black_bird_api_key =YAML.load(File.read('config/application.yml'))['BLACKBIRD_API_KEY']
end
it "should publish to blackbird" do
VCR.use_cassette 'publisher/create_user_response' do
expect(
Xaaron::Publishers::Users.publish_new_user({user: {
first_name: 'adsadsad', user_name: 'sasdasdasdsa' ,
email: 'asdassad@sample.com', auth_token: 'asdsadasdasdsa'
}}).code
).to eql 200
end
end
end
end
Runs fine on its own, creates the cassette, fails when run with all other tests due to webmock.
The Failure
Failure/Error: Xaaron::Publishers::Users.publish_new_user({user: {
WebMock::NetConnectNotAllowedError:
Real HTTP connections are disabled. Unregistered request: GET some_site_url_here with headers {'Http-Authorization'=>'api_key_here', 'User-Agent'=>'Typhoeus - https://github.com/typhoeus/typhoeus'}
You can stub this request with the following snippet:
stub_request(:get, "some site url here").
with(:headers => {'Http-Authorization'=>'some api key here', 'User-Agent'=>'Typhoeus - https://github.com/typhoeus/typhoeus'}).
to_return(:status => 200, :body => "", :headers => {})
Source: (StackOverflow)