views:

704

answers:

4

I'm writing a Rails plugin that includes some partials. I'd like to test the partials, but I'm having a hard time setting up a test that will render them. There's no associated controller, so I'm just faking one:

require 'action_controller'
require 'active_support'
require 'action_pack'
require 'action_view'

class MyTest < Test::Unit::TestCase
  def setup
    @renderer = ActionController::Base.new
    @renderer.append_view_path File.expand_path(File.join(File.dirname(__FILE__), '..', 'views'))
  end

  def test_renders_link
    result = @renderer.render(:partial => '/something')
    assert ...
  end
end

But that :render call always blows up. I've tried using an ActionView::Base instead of an ActionController::Base, but that gets even less far.

Has anyone had any success?

A: 

checkout ActionView::TestCase - http://api.rubyonrails.org/classes/ActionView/TestCase.html

You can also use these to test helpers, which I've found extremely helpful.

RSpec also has a way to test views: http://rspec.info/documentation/rails/writing/views.html

Hope that helps!

danpickett
Nothin' doing. I get all sorts of errors trying to call methods on nil. It's as though more setup needs to be done. Using ActionController::TestCase doesn't make it any better.
James A. Rosen
A: 

The closest I've gotten is

require 'action_controller'
require 'active_support'
require 'action_pack'
require 'action_view'
require 'action_controller/test_case'

class StubController < ActionController::Base
  append_view_path '...'
  def _renderizer;  render params[:args];  end
  def rescue_action(e) raise e end;
end

class MyTest < ActionController::TestCase
  self.controller_class = StubController
  def render(args);  get :_renderizer, :args => args;  end 
  def test_xxx
    render :partial => ...
  end
end

But I get a routing error now: ActionController::RoutingError: No route matches {:action=>"_renderizer", :controller=>"", :args=>{:locals=>{:...}, :partial=>"/my_partial"}}

James A. Rosen
+1  A: 

The final answer:

require 'action_controller'
require 'active_support'
require 'action_pack'
require 'action_view'
require 'action_controller/test_case'

class StubController < ActionController::Base
  helper MyHelper
  append_view_path '...'
  attr_accessor :thing
  def my_partial
    render :partial => '/my_partial', :locals => { :thing => thing }
  end
  def rescue_action(e) raise e end;
end

class MyTestCase < ActionController::TestCase
  self.controller_class = StubController
  def setup
    @controller.thing = ...
    get :my_partial
    assert ...
  end
end
James A. Rosen
A: 

I suggest you look at the code for the resource_controller plugin. I've also seen the approach in a few other plugins.

The answer is simple, in the test directory, you create an app that uses your plugin. From there, you simply use the common tools to test Rails views.

The test app can be extremely simple if there aren't many different use cases for your plugin. In the case of more complex plugins, like resource_controller, you'll probably have to create quite a few different controllers and so on.

To trick your test app into loading your plugin, the simplest way is to create a link to the root of the r_c directory inside the test app's plugin directory. This isn't gonna work on Windows, only POSIX OSes.

webmat