[LRUG] Parameterising a Rails 3 controller mixin

Murray Steele murray.steele at gmail.com
Tue Oct 4 05:33:56 PDT 2011


Can't you test the ControllerMixin directly?

something like (written in email client, apologies for all the wrongness):

class ControllerMixinTest < ActiveSupport::TestCase

  class MyTest; end

  test "the controller mixin supplies a current_foo when MyEngine.model is
'foo'" do
    MyEngine.model = 'foo'

    assert !MyTest.new.responds_to?(:current_foo)

    MyTest.include ControllerMixin # or however it's supposed to be mixed in

    assert MyTest.new.responds_to?(:current_foo)
  end

  # Then continue on to test what this magical current_foo method does.
end

On 4 October 2011 13:27, Andrew Stewart <boss at airbladesoftware.com> wrote:

> Hola El Rug,
>
> I have a Rails 3 engine which mixes a module into ActionController::Base.
>  The module provides helper methods in the controller such as `current_foo`.
>
> Now, however, I want to parameterise those methods based on a configuration
> value.  So if somebody has a Bar model instead of a Foo model, the
> controller will get a `current_bar` method.
>
> I think I have a working solution but I can't figure out how to test it.
>  Here's what I've got:
>
>    module ControllerMixin
>      # original hard-coded method:
>      # def current_foo
>      #   @current_foo ||= Foo.find(session[:current_foo_id]) if
> session[:current_foo_id]
>      # end
>
>      # parameterisable method:
>      class_eval <<-END
>        def current_#{MyEngine.model} ||=
> #{MyEngine.model.classify.constantize}.find(session[:current_#{...}_id]) if
> ...
>      END
>    end
>
> -- where MyEngine.model is set to 'foo' or 'bar' or whatever in an
> initializer (defaults to 'foo').
>
> This appears to work when I use it in a Rails app, but I can't test the
> 'bar' case in the engine's gem because the Rails app has already initialised
> with the default value 'foo' before my test's setup method can set it to
> 'bar'.  I.e.:
>
>    class BarTest < ActiveSupport::TestCase
>      setup do
>        MyEngine.model = 'bar'  # too late!  ActionController::Base already
> has default `current_foo` mixed in
>      end
>
>      test 'current_bar correctly defined' do
>        ...  # fails because `current_foo` exists, not `current_bar`
>      end
>    end
>
> Any ideas?  Maybe a lazy-loading alternative to the class_eval approach or
> somehow setting MyEnding.model before Rails spins up...?
>
> Cheers,
> Andy Stewart
>
> -------
> http://airbladesoftware.com
> _______________________________________________
> Chat mailing list
> Chat at lists.lrug.org
> http://lists.lrug.org/listinfo.cgi/chat-lrug.org
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lrug.org/pipermail/chat-lrug.org/attachments/20111004/e6d71a3b/attachment.html>


More information about the Chat mailing list