[rspec-users] Controller specs and default_url_options

295 views
Skip to first unread message

Titinux

unread,
Jan 16, 2012, 6:17:54 PM1/16/12
to rspec...@rubyforge.org
Hello,

I'm using Rails 3.1.3 with rspec-rails 2.8.1. I have a scope ':locale'
in routes.rb and I want to run controller and routing
specs. I'm aware of the problem with setting default_url_options in
application.rb controller so I apply the solution found in the last
comment on rspec issue #255 ( https://github.com/rspec/rspec-rails/issues/255
)

#./spec/support/default_locale.rb
class ActionView::TestCase::TestController
def default_url_options(options={})
{ :locale => I18n.default_locale }
end
end

class ActionDispatch::Routing::RouteSet
def default_url_options(options={})
{ :locale => I18n.default_locale }
end
end

#./spec/controllers/categories_controller_spec.rb
require "spec_helper"

describe CategoriesController do

describe "GET index" do
it "assigns all categories as @categories" do
category = Factory :category

get :index
assigns(:categories).to_a.should eq([category])
end
end
end

This test fails with routing error but if I use "get :index,
locale: :fr" instead of just "get :index" the test pass.
This test is a example of controller spec but I have failing tests for
routing and request. (I have no view specs but
I'm pretty sure they would also fail)

I can't figure out where the problem come from and why the patch
doesn't solve it. Is there another thing to do ? (I just put the code
in ./spec/support/default_locale.rb and verify that it loads
correctly).

Thanks in advance.
_______________________________________________
rspec-users mailing list
rspec...@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

David Chelimsky

unread,
Jan 16, 2012, 8:18:52 PM1/16/12
to rspec-users

No guarantees here, but it's possible that ActionView::TestCase::TestController is not loaded yet, in which case its own definition of default_url_options would clobber yours when it does get loaded. Try this instead:

ActionView::TestCase::TestController.class_eval do
undef_method :default_url_options


def default_url_options(options={})
{ :locale => I18n.default_locale }
end
end

ActionDispatch::Routing::RouteSet.class_eval do
undef_method :default_url_options


def default_url_options(options={})
{ :locale => I18n.default_locale }
end
end

If those classes aren't loaded yet, Rails will find and load them first (via its autoload strategy) before invoking class_eval on them, thus ensuring that you're replacing the existing methods rather than writing methods that will later be replaced.

HTH,
David

Titinux

unread,
Jan 17, 2012, 9:23:24 AM1/17/12
to rspec...@rubyforge.org
Hi,

I used your code but it does not work either.

To eliminate the possibility of a problem coming from my application I
made a new Rails 3.1.3 app from scratch and scaffold Category stuff.

And the result is that view specs start working with either issue #255
solution or yours but controller, routing and request specs fails
whatever I try.

I've set a "binding.pry" just before "get :index" in the controller
spec to have a better vision of what's going on

ActionView::TestCase::TestController.new.default_url_options =>
{:locale=>:en}
ActionDispatch::Routing::RouteSet.new.default_url_options =>
{:locale=>:en}

So I think the patch does its job but "get :index" takes another path
and not use default_url_options from
ActionView::TestCase::TestController nor
ActionDispatch::Routing::RouteSet


On 17 jan, 02:18, David Chelimsky <dchelim...@gmail.com> wrote:
> On Jan 16, 2012, at 5:17 PM, Titinux wrote:
>
>
>
>
>
>
>
>
>
> > Hello,
>
> > I'm using Rails 3.1.3 with rspec-rails 2.8.1. I have a scope ':locale'
> > in routes.rb and I want to run controller and routing
> > specs. I'm aware of the problem with setting default_url_options in
> > application.rb controller so I apply the solution found in the last

> > comment on rspec issue #255 (https://github.com/rspec/rspec-rails/issues/255

> rspec-us...@rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users

Martin C.

unread,
Jan 19, 2012, 11:45:00 AM1/19/12
to rspec...@rubyforge.org
Hi Jeremie,

I'm also using Rails 3.1.3 and rspec-rails 2.8.1 and I was in the same
situation as you: neither the rspec issue #255 or the proposed solutions
in this email thread solved my problems. But now I have something
working for me (and hopefully it will work for you too).

As I recently posted on Stackoverflow
(http://stackoverflow.com/questions/1987354/how-to-set-locale-default-url-options-for-functional-tests-rails/8920258#8920258
), here is the code I use to inject the locale in the controller's
params (which makes all my controller specs pass without explicitly
specifying the locale in each controller spec):

class ActionController::TestCase
module Behavior
def process_with_default_locale(action, parameters = nil, session =
nil, flash = nil, http_method = 'GET')
parameters = { :locale => I18n.default_locale }.merge( parameters
|| {} )
process_without_default_locale(action, parameters, session, flash,
http_method)
end
alias_method_chain :process, :default_locale
end
end


And here is the "cheat" I use to inject the locale in Rails's
assert_recognizes method (which makes all my routing specs pass without
explicitly specifying the locale in each routing spec):

module ActionDispatch::Assertions::RoutingAssertions
def assert_recognizes_with_default_locale(expected_options, path,
extras={}, message=nil)
expected_options = { :locale => I18n.default_locale.to_s
}.merge(expected_options || {} )
assert_recognizes_without_default_locale(expected_options, path,
extras, message)
end
alias_method_chain :assert_recognizes, :default_locale
end


Stucking those two code snippets in my spec helper class means that I do
not need to change all my previous controller/routing specs during the
implementation of supporting multiple locales for my app.

Hope this helps,

Martin

--
Posted via http://www.ruby-forum.com/.

Joshua Muheim

unread,
Nov 12, 2012, 10:07:40 AM11/12/12
to rspec...@rubyforge.org
Thanks for these very useful informations.

I found the titinux' first post to solve my problems with request specs,
and martin_c94's post to solve my controller specs problems.

Still, in the console, the url helpers need the locale explicitly set,
it seems:

[1] pry(main)> app.user_path User.first
ActionController::RoutingError: No route matches {:action=>"show",
:controller=>"users", :locale=>#<User _id: 509fc01d77bb1................

Interestingly, when executing the following code block (which is also
used to fix the problem with the request specs) within the console, it
works!

[2] pry(main)> class ActionDispatch::Routing::RouteSet
[2] pry(main)* def default_url_options(options={})
[2] pry(main)* { :locale => I18n.default_locale }
[2] pry(main)* end
[2] pry(main)* end
=> nil
[3] pry(main)> app.user_path User.first
=> "/de/users/509fc01d77bb1e6a050000a0"

I'm not sure whether this would be a valid fix also for the console?? Do
you guys experience the same behavior??
Reply all
Reply to author
Forward
0 new messages