Skip to content

Instantly share code, notes, and snippets.

@iansheridan
Forked from adamstrickland/api.feature
Created July 20, 2011 11:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iansheridan/1094833 to your computer and use it in GitHub Desktop.
Save iansheridan/1094833 to your computer and use it in GitHub Desktop.
Cucumber Example for testing a RESTful API
Scenario: Get List of My Hitchhiking Items via API
Given the existing things:
|name|
|The Guide (duh)|
|A towel|
|Sub-Etha Sens-O-Matic|
|Pan Galactic Gargle Blaster|
|Kill-o-Zap blaster pistol|
And the existing accounts:
|email|name|password|
|ford@hhgttg.com|Arthur Dent|Praxibetel Ix|
And the account with email "ford@hhgttg.com" has a thing named "A towel"
And the account with email "ford@hhgttg.com" has a thing named "Sub-Etha Sens-O-Matic"
When I request the "my things" endpoint using credentials "ford@hhgttg.com":"Praxibetel Ix"
Then I should receive a json list like:
|name|
|A towel|
|Sub-Etha Sens-O-Matic|
Scenario: Use Nutrimatic Drink Dispenser
Given the existing accounts:
|email|name|password|
|arthur@hhgttg.com|Arthur Dent|dolphin|
When I request the "dispense drink 'tea'" endpoint with credentials "arthur@hhgttg.com":"dolphin"
Then I should receive a json hash like:
|description|
|a concoction 'almost, but not quite entirely unlike tea'|
def visit_endpoint(endpoint, data={}, params={})
params[:format] ||= 'json'
args = case endpoint
when /^my things$/i
visit account_things_path(params), :get
when /^dispense drink '([^']*)'$/i
visit account_drinks_path(params), :post, {:drink => $1}
else raise "No endpoint mapping for '#{endpoint}'"
end
@response
end
def from_json(response)
response.should be_success
ActiveSupport::JSON.decode(response.body)
end
def compare_json_list_to_table(json_list, table)
json_list.should have(table.rows.size).items
table.hashes.each do |table_row_hash|
#ordering can be shaky, so need to find the right item in the json list
pk = table.headers.first
json_hash = json_list.detect{|jh| (jh[pk] || jh[pk.to_sym]) == table_row_hash[pk] }
raise "JSON array did not contain a hash containing #{pk} => #{table_row_hash[pk]}. Be sure to put your PK in the first column of the table." unless json_hash
compare_json_hash_to_table_row_hash(json_hash, table_row_hash)
end
end
def compare_json_hash_to_table_row_hash(json_hash, table_row_hash)
table_row_hash.each do |key, control|
test = json_hash[key] || json_hash[key.to_sym]
if control == '*' # wildcard; just test that key exists, value is irrelevant or volatile
test.to_s.should_not be_empty
else
test.to_s.should eql control
end
end
end
def visit_authenticated_endpoint(endpoint, credentials, data={}, params={})
basic_auth(credentials[:user], credentials[:password])
visit_endpoint(endpoint, data, params)
end
When /^I request the "([^"]*)" endpoint using credentials "([^"]*)":"([^"]*)"$/ do |endpoint, email, pwd|
visit_authenticated_endpoint(endpoint, {:user => email, :password => pwd})
end
When /^I request the "([^"]*)" endpoint$/ do |endpoint, email, pwd|
visit_endpoint(endpoint)
end
Then /^I should receive a json list like:$/ do |table|
compare_json_list_to_table(from_json(@response), table)
end
Then /^I should receive a json hash like:$/ do |table|
compare_json_hash_to_table_row_hash(from_json(@response), table.hashes.first)
end
Given /^the existing ([a-zA-Z0-9]+s):$/ do |klasses, table|
klass = klasses.singularize.camelize.constantize
table.hashes.each do |row|
klass.make(row) #uses machinist
end
end

=== Notes

I have made some changes so that this uses factory_girl and hashie

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment