We here at Near-Time have been using the Rails plugin ValidatesCaptcha from Tore Darell for the last couple of months. The plugin worked great after I submitted a patch that fixed an issue with multiple calls to valid? deleting the CAPTCHA.
As a solution, it was great—I dropped it in, fought with RMagick and then had the spam on lockdown. But I was bugged that the docs omitted anything about how to functionally test the new validation. So I had to solve the problem. Here is some sample code for testing a model validated with a CAPTCHA via ValidatesCaptcha, straight from the Near-Time source code:
def test_create_anonymous_comment
@session[:user_id] = nil
challenge = AngryMidgetPluginsInc::CaptchaImageChallenge.new
challenge.generate
challenge.write
xhr(:post, :create,
{ :update_id => "uniq_1",
:commit => "add",
:context => spaces(:public_space).subdomain,
:comment => { :body => "Some unique comment",
:name => ‘Anonymous User’,
:email => ‘sbw@ibiblio.org’,
:url => ‘http://www.thatswhatimtalkingabout.org/’,
:ip_address => ‘154.65.2.187’,
:captcha_id => challenge.id,
:captcha_validation => challenge.string,
:commentable_id => pages(:public_news_page).id,
:commentable_type => ‘Page’} }, @session)
assert_response :success
assert_equal AnonymousComment, assigns(:comment).class
end
And here’s a similar bit for testing (not very different, but the novice may miss it):
challenge = AngryMidgetPluginsInc::CaptchaImageChallenge.new
challenge.generate
challenge.write
comment = AnonymousComment.create(:body => ‘some anonymous comment’,
:ip_address => ‘154.65.2.187’,
:captcha_id => challenge.id,
:captcha_validation => challenge.string,
:commentable => pages(:my_first_page))
The challenge object creation and write is magic that is generally handled for you behind the scenes by the plugin. This is the double edged sword of Rails plugins—they can offer you so much return on a few commands, but at the price that your app is less testable and you don’t understand what is hiding behind the abstraction.

RSS
Tore Darell said 9/19/06
Glad you find the plugin useful, and thanks for the patches! I’ve been updating it quite a lot in the last few days now, so it should be a bit more robust. The challenges will now always validate by default when in test mode, so that unit tests won’t suddenly start failing because of it. If you still want to test the validation in your models, this behaviour can be turned off in config/captcha.yml. I’ve also added another type of challenge, in which the user answers a simple question to prove he’s not a robot. It should be a lot more accessible than the image version. There is also a new captcha_valid? controller method that, if used, keeps the model from knowing anything about the CAPTCHA.