To prevent bots from Signing up on our application, we added a captcha to our User model. We used the validates_captcha plugin available at http://svn.2750flesk.com/validates_captcha/trunk

The plugin, selects text from a String array for the captcha challenges, so, Sur, my co-programmer, hacked the plugin a little to add random text and improved images.

After adding the plugin we realized that all our tests which validate the User model had started failing. Programmatcially a test case or a bot are not much different, they are both scripts.

Mocks to the rescue.

Here is what I wrote in a file named add_captcha_to_active_record.rb under test/mocks/test directory.

require File.expand_path(File.dirname(__FILE__) +
"/../../../vendor/plugins/validate_captcha/lib/add_captcha_to_active_record")

module AngryMidgetPluginsInc #:nodoc:

	module Validations #:nodoc:

		# module Captcha
		module Captcha #:nodoc:

			# module InstanceMethods
			module InstanceMethods #:nodoc:

			private

				def validate_captcha(options = {}) #:nodoc:

				end

			end

		end#module Captcha

	end#module Validations

end#module AngryMidgetPluginsInc

What I have done by adding this file is, I have asked the test scripts to use the validates_captcha method in /test/mocks/test/add_captcha_to_active_record.rb instead of the validates_captcha method in plugins/validate_captcha/lib/add_captcha_to_active_record.rb

Well actually Rails does all the magic, I just need to give the same file name as the one I want to mock and then define the method that I want to override.

The original validates_captcha method checks that the text entered on the signup screen is the same as that stored on the server. If these do not match it adds a validation error to the base class, the User class in our case.
In the mock validates_captcha method we just do nothing. So a validation error will never be added to the base class.

And now our tests are running and passing again.

I also noted the presence of a directory /test/mocks/development/ … well that means I can even mock classes in the development environment.
One of our application, connects to Paypal to make a payment and then returns back. During development we had commented out this code so that we are not sent to paypal everytime. Now I know how I can avoid commenting or changing the code by using mock objects.
I will be working on that soon and blog about my experiences here.

Share this:

Privacy Preference Center