Savon::Spec
Savon testing library
Installation
Savon::Spec is available through Rubygems and can be installed via:
$ gem install savon_spec
Dependencies
Currently, the dependencies are very strict. Savon::Spec is meant to be used with:
Note to self: the required versions for RSpec and Mocha could probably be lower.
Getting started
Macros
Include the Savon::Spec::Macros
module:
RSpec.configure do |config|
config.include Savon::Spec::Macros
end
Mock
By including the macros, you have access to the savon
method in your specs. It returns a Savon::Spec::Mock
instance to set up your expectations. It's based on Mocha and comes with similiar methods:
#expects(soap_action) # mocks SOAP request to a given SOAP action
#stubs(soap_action) # stubs SOAP requests to a given SOAP action
#with(soap_body) # expects Savon to send a given SOAP body
#raises_soap_fault # raises or acts like there was a SOAP fault
#returns(response) # returns the given response
Fixtures
Savon::Spec works best with SOAP response fixtures (simple XML files) and a conventional folder structure:
~ spec
~ fixtures
~ get_user
- single_user.xml
- multiple_users.xml
+ models
+ controllers
+ helpers
+ views
When used inside a Rails 3 application, Savon::Spec uses the command Rails.root.join("spec", "fixtures")
to locate your fixture directory. In any other case, you have to manually set the fixture path via:
Savon::Spec::Fixture.path = File.("../fixtures", __FILE__)
The directories inside the fixture directory should map to SOAP actions and the XML fixtures inside those directories should describe the SOAP response. Please take a look at the following examples to better understand this convention.
An example
user.rb
class User
def self.all
response = client.request :get_all_users
response.to_hash.map { |user_hash| new user_hash }
end
def self.find(user_id)
response = client.request :get_user do
soap.body = { :id => user_id }
end
new response.to_hash
end
end
user_spec.rb
describe User do
describe ".all" do
before do
savon.expects(:get_all_users).returns(:multiple_users)
end
it "should return an Array of Users" do
User.all.each { |user| user.should be_a(User) }
end
it "should return exactly 7 Users" do
User.all.should have(7).items
end
end
describe ".find" do
before do
savon.expects(:get_user).with(:id => 1).returns(:single_user)
end
it "should return a User for a given :id" do
User.find(1).should be_a(User)
end
end
end