December 16, 2008

Posted by John

Tagged gems, stump, testing, and wufoo

Older: Deploying Sinatra on Dreamhost With Passenger

Newer: The 2008 Smörgåsbord

Using Context and Stump to HTTParty like a Wufoo

A while back, we (Ordered List) used Wufoo for a content management survey (results). It worked out great, and since we’ve been having some issues with our project request form, we decided to switch it to Wufoo as well.

Wufoo, The Gem

After a quick google/github/rubyforge search revealed nothing much in the way of Ruby code for Wufoo, I decided to roll my own. Wufoo has a simple JSON API, so obviously HTTParty fit the bill. Because I built this out of need and not want, I only wrapped the submission part of Wufoo’s api. I might do the rest some other time, but until then others can feel free to fork it and fill in the holes. Here is an example of submitting something to Wufoo, including validation checks

require 'rubygems'
require 'wufoo'

client = Wufoo::Client.new('http://orderedlist.wufoo.com', 'YOUR API KEY')
submission = Wufoo::Submission.new(client, 'your-form-name')

response = submission.add_params({
  '1'  => 'John Nunemaker',
  '2'  => 'nunemaker@gmail.com',
  '3'  => 'Holla! What up?',
}).process

if response.success?
  puts response.message
else
  if response.fail?
    puts response.error    
  end
  
  unless response.valid?
    errors = response.errors.collect { |e| "#{e.field_id} (#{e.code}): #{e.message}" }    
    puts errors * "\n"
  end
end

Nice and easy. You can install the gem from github:

# from rubyforge
sudo gem install wufoo

# from github
sudo gem install jnunemaker-wufoo --source http://gems.github.com

Context and Stump

I started adding some simple test cases pretty much from the start. The thing about testing web services though is at some point you need to make sure that you aren’t actually hitting the service from your tests. Just as I reached for mocha, I remembered Jeremy’s new library stump. I thought what the heck, installed it and stubbed away the post call.

stump has very similar syntax to RSpec, with the exception being that you use the :return key instead of chaining method calls to specify the response you would like to return. See the before block in the test case below for an example.

Since I was already using stump, I figured I might as well try context, Jeremy’s other new gem, that allows for specifying context’s and RSpec style declarations inside your test unit test cases. Below is an example of one context from the Wufoo gem I mentioned above.

class TestSubmission < Test::Unit::TestCase
  context 'processing a response that failed' do
    before do
      @client.stub!(:post, :return => error_response_data)
      submission = Wufoo::Submission.new(@client, 'my-crazy-form').add_params({'0' => 'Foobar!'})
      @response = submission.process
    end
  
    test 'should have data' do
      assert_equal(error_response_data, @response.data)
    end
  
    test 'should not be success?' do
      assert ! @response.success?
    end
  
    test 'should be a fail?' do
      assert @response.fail?
    end
  
    test 'should be valid?' do
      assert @response.valid?
    end

    test 'should have error' do
      assert_equal('The supplied form URL was not found.', @response.error)
    end
  end
end

You can view the full test case on Github, but you get the idea. Context gives you context blocks to wrap around chunks of tests and also gives you the fancy test block setup to define test methods like Rails. I think these two subtle additions make it much easier to read your tests because you don’t have to mentally replace underscores with spaces.

Context also supports rspec style describe/it blocks and shoulda style context/should blocks. It also supports RSpec’s shared examples functionality which I’ve grown to like. Jeremy has several examples in the readme file of the gem. Be sure to check them out.

Conclusion

Context and stump “feel” really light because in fact they are. This is good and bad. A few times I found myself reaching for things that I would normally do in RSpec, that I couldn’t in stump (or at least couldn’t figure out after a quick glance).

That said, I like the idea of building on top of a core library and breaking up the context, stump and matchy functionality into different gems. Matchy, which I had not mentioned until just now, adds RSpec’s matching functionality to test unit. I’ll definitely be using these more in the future and would recommend you give them a shot too.

0 Comments

Sorry, comments are closed for this article to ease the burden of pruning spam.

About

Authored by John Nunemaker (Noo-neh-maker), a programmer who has fallen deeply in love with Ruby. Learn More.

Projects

Flipper
Release your software more often with fewer problems.
Flip your features.