Showing posts with label Rails. Show all posts
Showing posts with label Rails. Show all posts

Monday, January 18, 2010

Testing ActiveResource classes with Fakeweb and Shoulda

It is not as simple to write unit tests for Active Resource models as they often depend on external web service. It is not mostly possible to get or create a Sandbox web service for unit testing your Active Resource classes. In such scenario you need a way to mock how the RESTful web service would behave in production.

I initially tried to use HttpMock which is used to test Active Resource framework within Rails. It is undocumented and you need to dig through web and Rails documentation it self to see how it works. Recently I came across excellent FakeWeb gem and ever since that I have been hooked on it. I am impressed by simplicity with which we I can mock RESTFul Rails web services.

Here is how I use Test::Unit and Shoulda with Rails to Mock RESTful web services for Active Resource classes. I am using XML based web services so I needed sample XML responses that Mock service should return. I create XML files containing those sample responses and store them under test/fixtures folder. After that I edited test_helper.rb file in test folder to have this utility method which loads sample responses from XML files located in fixtures folder.



After this lets jump on to unit test that we are going to write for our Active Resource class. Lets say we are testing an Active Resource class named User. Here is how I write unit test with FakeWeb and Shoulda gem.



First I am requiring both FakeWeb and Shoulda a gem. I would also add these gems to config/environments/test.rb as required gem for test environment.



After requiring these two gems I would disable real HTTP connections so not to mix real Web services calls with mock RESTful Web services by setting allow_net_connect property of FakeWeb class to false. Similarly in teardown method I would re-enable net HTTP connections by setting allow_net_connect property to true.

Now I am going to write actual test using FakeWeb within Shoulda context blocks.



Here within the context block I am setting up url to register as GET request to return response that is contained in XML file. After that a simple test checks the returned response object with some assertions. This shows how easy it is to create mock RESTful web services with FakeWeb and test your Active Resource classes with RSpec or  Test::Unit

Monday, May 11, 2009

Deploying rails applications with vlad

Vlad is application deployment automation tool much like Capistrano but with much less complexity and it integrates right into rake. so no need to capify your project again. Vlad is based on standard nix tools like ssh and rsync .

To make it even better is that it comes with built in support for number of version control systems like Darcs, Subversion, Mercurial and best of all Git. To get started you need to install vlad gem on your machine and on each of servers you wish to deploy your ruby app.

sudo gem install vlad


The variables for deployment are typically setup in config/deploy.rb file just like capistrano. For trival one server deployment all you have to do is set four vaiables in deploy.rb file


set :application, "myblog"
set :domain, "blog.com"
set :deploy_to, "/var/rails/myblog"
set :repository", "http://svn.myserver.com/myblog/trunk"


Also add following lines to Rakefile as well to require vlad gem


Begin
require 'vlad'
Vlad.load
rescue LoadError
#do nothing
end


Just run following commands in this sequence to deploy your application


vlad:setup #run first time only
vlad:update
vlad:migrate #optional
vlad:start


As you might be aware Capistrano is not going to be maintained anymore by Jamis buck and there is lot of active development going on for vlad it should be good idea to give vlad a spin as alternative to capistrano.

DHH speaks of 5 years of ruby on rails and rails 3

DHH's keynote on Railsconf 2009 speaks about five years of ruby on rails. Rails 3 and secret of high productivity.

Tuesday, March 10, 2009

using multiple contexts block in test case with shoulda

Test::Unit which is a default unit testing framework with rails. It has only one context for each test case class. If we can have more than one context per class than it could reduce number of files and classes that we are required to make to test cases in multiple contexts.


Answer to this issue is support for multiple contexts in Shoulda. Shoulda is rspec like testing framework built upon Test::Unit. Shoulda allows you to have multiple context with thier own setup and teardown methods. For example see this context block in a test case




class UserTest < Test::Unit::TestCase
context "with user" do
setup do
@user = User.create(:login => "john", :password => "secret" )
end

should "be able to authenticate" do
assert User.authenticate("john", "secret")
end

should "return authenticated user" do
assert_equal @user, User.authenticate("john", "secret")
end
end
end


For more details on shoulda testing framework take a look at official rails wiki page

Tuesday, July 15, 2008

Install Phusion Passenger on Cent OS 5

Phusion Passenger (mod_rails/mod_rack) is an apache module that makes deployment of Ruby/Rails applications as simple as PHP applications. It does not require use of any ruby specific tools to deploy application. All you have to do is copy your source files in appropriate directories on server and your code changes will be deployed. Main advantage of passenger is it allows to deploy rails application reliably on shared hosting environment. Passenger is not available for windows. 

Lets see how to install Passenger on Cent OS. Cent OS 5.1 comes with Apache 2.2.3 installed. First of all make sure Ruby, Gems, Rails and ruby development headers is installed on the system, Issue following commands as root: 

yum install ruby
yum install irb
yum install rdoc
yum install ruby-devel
yum install rubygems
Now install rails gems:

gem install rails -y

Also install Apache development header files.

yum install httpd-devel
Now we have all prerequisites covered. Lets proceed with installation of Passenger gem.

gem install passenger
After installing passenger and its dependencies make sure that Apache is stopped, launch passenger installer for Apache module from command line.

passenger-install-apache2-module

The command line based installer is pretty good it will check all dependencies and inform you if any dependency is missing. After the module is installed. create a rails application in /var/www/htdocs folder.

rails demo
Now open httpd.conf file in /etc/httpd/conf folder. Add following lines in this file.

LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-2.0.1/ext/apache2/mod_passenger.so
PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-2.0.1
PassengerRuby /usr/bin/ruby

These paths could be different for your system. Now lets configure virtual host for rails application at bottom of httpd.conf. Add these lines at bottom of file:

<VirtualHost *:80>
      ServerName www.demo.com
      DocumentRoot /var/www/html/myapp/public
</VirtualHost>
Make sure DocumentRoot points to public directory of your rails application. Also add server name alias to hosts file in /etc/ folder. Now start apache server from console.

service httpd start
Your new rails application should be running now with Phusion Passenger.

Tuesday, February 26, 2008

Getting TinyMCE 3.0 Spellchecker to work with Rails

In new version of TinyMCE editor there are many changes in plug ins. The Plug in code is changed. The popular spell checker plug in now uses JSON as transport mechanism instead of XML. In my example we are using Aspell to check spellings, so you must have Aspell installed on your system for this example to work

Issue this command on CLI to check if Aspell is installed:

% aspell


You should see help output related to command

First of all you need to install JSON gem to parse JSON requests

% sudo gem install json


Then write this action in a controller:

require json

def spellcheck
raw = request.env['RAW_POST_DATA']
req = JSON.parse(raw)
lang = req["params"][0]
if req["method"] == 'checkWords'
text_to_check = req["params"][1].join(" ")
else
text_to_check = req["params"][1]
end
suggestions = check_spelling_new(text_to_check, req["method"], lang)
render :json => {"id" => nil, "result" => suggestions, "error" => nil}.to_json
return
end


Now also write this method in private section of controller:

def check_spelling_new(spell_check_text, command, lang)
json_response_values = Array.new
spell_check_response = `echo "#{spell_check_text}" | aspell -a -l #{lang}`
if (spell_check_response != '')
spelling_errors = spell_check_response.split(' ').slice(1..-1)
if (command == 'checkWords')
i = 0
while i < spelling_errors.length
spelling_errors[i].strip!
if (spelling_errors[i].to_s.index('&') == 0)
match_data = spelling_errors[i + 1]
json_response_values << match_data
end
i += 1
end
elsif (command == 'getSuggestions')
arr = spell_check_response.split(':')
suggestion_string = arr[1]
suggestions = suggestion_string.split(',')
for suggestion in suggestions
suggestion.strip!
json_response_values << suggestion
end
end
end
return json_response_values
end


now you need to open /plugins/spellchecker/editor_plugin.js file under your Tiny MCE directory. Search for this line;

t.url = url;


and change it to:

t.url = 'http://www.yourhostname.com';


then search for this line:

var t = this, url = t.editor.getParam("spellchecker_rpc_url", this.url+'/rpc.php');


and change it to:

var t = this, url = t.editor.getParam("spellchecker_rpc_url", this.url+'/spellcheck');


and to make this work just add this route to routes.rb under config folder

map.connect '/spellcheck', :controller => 'your_controller_name', :action => 'spellcheck'
#replace your_controller_name with name of our controller in which the spellcheck action is written