Using simply_helpful with rspec controller tests
Rspec currently doesn't play well on Edge Rails with the simply_helpful plugin.
The cause
simply_helpful plugin hook (init.rb):
require 'simply_helpful'
ActionController::Base.send :include, SimplyHelpful::RecordIdentificationHelper
ActionController::Base.helper SimplyHelpful::RecordIdentificationHelper, SimplyHelpful::RecordTagHelper
Rspec's ActionController::Base definition (lib/extensions/action_controller/base.rb):
module ActionController
class Base
end
end
ActionController::Base is stripped from all modules included with the
ActionController::Base.send :include, SomeModule
syntax.
Monkey patch to fix
Include in spec/spec_helper.rb, before your Test::Rails::TestCase definition:
module Spec
module Rails
class ControllerContext < Rails::Context
module ContextEvalInstanceMethods
def setup_extra
(class << @controller; self; end).class_eval do
include ControllerInstanceMethods
end
@controller.integrate_views! if @integrate_views
@controller.session = session
#extend the controller instance with simply_helpful modules
@controller.extend SimplyHelpful::RecordIdentificationHelper
@controller.class.helper SimplyHelpful::RecordIdentificationHelper, SimplyHelpful::RecordTagHelper
end
end
end
end
end
Running controller/view specifications using simplyhelpful helper methods, such as domid(), should not raise NoMethodErrors anymore.
Inline RJS in respond_to blocks
This snippet chokes (see comments) when referenced from a controller specification in isolation mode:
#@language is set in a before_filter
def create
@account.supported_languages << @language
#@language != nil
respond_to do |format|
format.js { #@language != nil
render :update do |page|
#@language is nil
page.replace( dom_id( @language ), :partial => 'shared/admin/language', :locals => { :language => @language } )
page.visual_effect :highlight, dom_id( @language )
page.call('Marmalade.Messaging.flash', 'success', "Added language %s" / @language.to_s)
end }
format.xml { @account.languages.to_xml }
end
end
Explicitly integrating views with
integrate_views
properly instantiates a JavaScriptGenerator object, thus preserving controller instance variables within the render :update block.
Any thoughts on this behaviour, or is inline RJS in respond_to blocks generally frowned upon?
Testing different content types with rspec
Rspec ( rather it's dependency ZenTest ) does not currently support content type headers for Controller testing using the Rspec on Rails plugin.
Monkey patch Test::Rails::ControllerTestCase
class Test::Rails::ControllerTestCase
%w(get put post head delete).each{|m| define_method(m.to_sym) do |*args|
@request.env['REQUEST_METHOD'] = m.upcase
@request.env['CONTENT_TYPE'] = Mime::EXTENSION_LOOKUP[(args[2].nil? ? 'html' : args[2].to_s )]
process( args[0], args[1] || {} )
end
}
end
Add the above to your Spec helper (spec/spec_helper.rb) after
require 'rspec_on_rails'
and before your Test::Rails::Testcase definition.
Examples
For the sake of saving keystrokes and taking the ability to add your own custom MIME Type extensions in consideration, pass the MIME Type extension (xml, html, js, rss, atom, yaml etc.) as the third argument.Defaults to html if not given.
get :index, {:locale => 'en'} #requests HTML content
get :index, {:locale => 'en'}, :html #requests HTML content
get :index, {:locale => 'en'}, :xml #requests XML content
get :index, {:locale => 'en'}, :js #requests Javascript content
View archives for November 2006.