SOAP webservices are widely used in enterprise environments. Although they feel a bit clumsy in comparison to slim REST services, sometimes you have to deal with them.
The great thing is, to test such a service you are often free to use any tool you like. I like RSpec!
To query a web service you just need a few lines of code. I recommend Savon as SOAP client. It is used as shown here:
require 'rubygems' require 'savon' WSDL_URL = 'http://www.webservicex.net/geoipservice.asmx?wsdl' client = Savon::Client.new WSDL_URL response = client.get_geo_ip do |soap| soap.body = { "wsdl:IPAddress" => "209.85.149.106" } end puts response
The response object can be converted to hash with the to_hash method, so you can fetch all values simply like you would do it with any other hash.
Now, the rest should be easy and is just a normal RSpec test:
require 'rubygems' require 'savon' WSDL_URL = 'http://www.webservicex.net/geoipservice.asmx?wsdl' RETURN_CODE_OK = "1" RETURN_CODE_ERROR = "0" describe "Geo IP Webservice at #{WSDL_URL}" do # helper method def get_geo_ip_result ip response = @client.get_geo_ip do |soap| soap.body = {"wsdl:IPAddress" => ip} end response.to_hash[:get_geo_ip_response][:get_geo_ip_result] end before :all do @client = Savon::Client.new WSDL_URL end it "should yield a country name" do result = get_geo_ip_result "209.85.149.106" result[:country_name].should_not be_nil result[:return_code].should eql(RETURN_CODE_OK) end it "should return error for malformed ip address" do result = get_geo_ip_result "not.an.ip.address" result[:return_code].should eql(RETURN_CODE_ERROR) end it "should fail if no ip address is submitted" do lambda { @client.get_geo_ip }.should raise_error end # ... endHappy testing!
EDIT:
@dbloete pointed me to the fact that with RSpec 2 you can expect errors even more readable:it "should fail if no ip address is submitted" do expect { @client.get_geo_ip }.to raise_error end
if you're using rspec and mocha, you could also try savon_spec (http://rubygems.org/gems/savon_spec) for non-integration tests based on soap response fixtures.
ReplyDeleteThanks for the hint. I'll try it!
ReplyDeleteHmmm, not sure about your specs. You are calling out the the web service each time you run the tests, there is no isolation here. Your tests will fail when the web service is down, even if your code is 100% correct. I think you should try to isolate your tests and only test the behavior.
ReplyDeleteHey Anonymous,
ReplyDeleteThese specs should fail if the service is down. That's exactly the point.
There are mainly three use cases to write tests like this:
- to be sure that a foreign service behaves like assumed/documented. ( And don't change over time )
- to have the safety that a service you provide works thru the hole stack.
- to reproduce/document/fix bugs.
Of course, I don't suggest to test the complete business logic thru a web service.
I hope I could clarify my motivation.
Cheers,
Arbo
Umm no. Think for a minute. Are you testing the web service? or are you testing your methods which makes SOAP requests to the said service? Your test case is depending on way too many factors. If you were using it for a method that was processing the response and returning some result, then if it fails you will need to check both whether your code had some problem or whether the service was down.
ReplyDeleteThank You and that i have a super proposal: What House Renovations Can You Claim On Tax house repair near me
ReplyDelete