in Ruby

Rails 3, SOAP and Testing, Oh My!

This past week at work I have had the “pleasure” of building out a SOAP endpoint for an internal system. This has caused me to find a wonderful new gem Wash Out (https://github.com/inossidabile/wash_out). With a feature comes with new test and with my first SOAP endpoint comes, how to test SOAP endpoints.

Testing a Wash Out controller wasn’t something that was blaintiantly obvious to me and took some experimenting and discussions with Boris Staal (@_inossidabile). Below is an example of how we settled on testing. This may not be the end all perfect solution but hopefully it will help you get started.

Let’s start with a sample controller, this will give us a base to refer to with our tests.

class API::GasPrices < ApplicationController
  include WashOut::SOAP
  soap_action "GetGasPrices", 
              :args   => {:postal_code => :integer}, 
              :return => :string
  def GetGasPrices
    render :soap => GasPrices.find_all_by_postal_code(params[:postal_code]).to_xml.to_s
  end
end

This controller is a fairly standard example, it has one method GetGasPrices and takes a postal_code as an argument. It returns a string of gas prices.

One of the things that we got caught on was how to actually hit the Wash Out gem and execute the HTTP request. To do that we’ll need to mount our app as a rack app.

We’ll need to make sure that we are using a version of the HTTPI gem that can use a Rack adapter. Right now we need to point our HTTPI gem at the GitHub repo. For the actual testing of making SOAP calls we can use Savon.

gem 'httpi', :git => 'https://github.com/savonrb/httpi.git'
gem 'savon'

Next we’ll need to create a spec file for our tests. For this example let’s use a request spec, even though this is a controller we actually want to make a request with SOAP to make sure our methods are recieving information correctly.

|~spec/
| |+requests/
| | |+API/
| | | |-gas_prices_controller_spec.rb

Let’s setup our spec file now, we’ll need to require Savon and the spec_helper.
Then create a describe block like below.

require 'spec_helper'
require 'savon'

describe API::GasPrices do
  HTTPI.adapter = :rack
  HTTPI::Adapter::Rack.mount 'application', MyGasPriceChecker::Application

  it 'can get gas prices for a postal code' do
    application_base = "http://application"
    client = Savon::Client.new({:wsdl => application_base + api_gas_prices_path })
      result = client.call(:get_gas_prices, :message =&gt; { :postal_code => 54703 })
    result.body[:get_gas_prices_response][:value].should_not be_nil
  end

Inside of our describe block we are using the HTTPI rack adapter, and then configuring that adapter to mount our MyGasPriceChecker as application. This will give us the ability to use the url http://application. In our test we’ll create a new Savon client, this client will need to access our WSDL so it can find the operations it has access too.

Once we have a client created our code can now actually call the GetGasPrices SOAP method. Our test then verifies that the value of our response is not nil, this is really just a starting point and we can iterate going forward to test actual return values.

Write a Comment

Comment

  1. Man, Thanks so much. I’ve got here through your issue on wash_out github. I am so glad that you did this blog post. It helped me a lot. Solved my problem.

    keep this great work.

    []‘s