Skip to content
This repository

isolated engine, routing helpers, testing? #6573

Closed
jrochkind opened this Issue · 19 comments

6 participants

Jonathan Rochkind Rafael Mendonça França Piotr Sarnacki SixArm Saurabh Nanda Steve Klabnik
Jonathan Rochkind

I believe there is no way to test isolated engine helpers or use isolated engine helpers in tests. But I'd be pleased if I'm wrong and I'm just missing something.

If you create an isolated engine, then the dummy app has a config/routes that has for instance mount Widget::Engine => "/widget"

If the Widget engines has it's own config/routes, then ordinarily an app with that line in it would be able to access the engine's route path helpers as widget.some_path.

That works in the app. But it does not work in the test environment. No such method widget, the widget. method isn't installed in the test environment.

The main engine root widget_path => /widget is installed in the testing environment, you can use it in tests and test routing involving that named helper and path. But not any of the specific widget routes that would ordinarily, in an actual app, be available at widget.some_path.

Phew, this is confusing to talk about, hope this is understandable.

Rafael Mendonça França
Owner

Please avoid questions in the issues tracker. Use mailing lists as rails talk or stack overflow

Rafael Mendonça França rafaelfranca closed this
Rafael Mendonça França
Owner

Fixed the link.

Jonathan Rochkind

I believe it's a missing feature/bug, rather than a question.

Rails 3.1/3.2 added isolated engines. But the testing environment has not kept pace to make it possible to test features that were added.

This is not an appropriate thing for the issue tracker? But okay, I'll post it to the listserv, and maybe someone else will post an issue, maybe not, maybe someday it'll get fixed, maybe not, no problem.

Rafael Mendonça França
Owner

@jrochkind you post sound like a question. But I'll ask feedback from @drogus .

Rafael Mendonça França
Owner

@jrochkind it was fixed at 6525002.

Thanks @drogus :+1:

Piotr Sarnacki
Collaborator
drogus commented

For me it's valid issue. It's really easy to include those helpers by yourself if you know how to do it, but I see no reason to make it hard for developers. I fixed it here: 6525002

I think that it would be good to also backport it to 3-2-stable. What do you guys think?

Rafael Mendonça França
Owner

I'm fine with the backport.

Nathaniel Bibler nbibler referenced this issue from a commit
Piotr Sarnacki Include routes.mounted_helpers into integration tests
In integration tests, you might want to use helpers from engines that
you mounted in your application. It's not hard to add it by yourself,
but it's unneeded boilerplate. mounted_helpers are now included by
default. That means that given engine mounted like:

    mount Foo::Engine => "/foo", :as => "foo"

you will be able to use paths from this engine in tests this way:

    foo.root_path #=> "/foo"

(closes #6573)
6525002
Jonathan Rochkind

@drogus, thanks!

It might be good to backport to 3.2 -- but it seems as if it's possible simple instructions could be provided for relatively short code to manually include in your 3.2.x app, to support this behavior?

It's really easy to include those helpers by yourself if you know how to do it,

I'm having trouble figuring out what those instructions would be from the patch, myself. Clearly I don't know how to do it. :)

But if you could provide such instructions, it would be of immediate use to me in my 3.2.x app, and may obviate the need to backport to 3.2.x, if workaround instructions can be provided.

I agree that ideally Rails ought to Just Work here, as per your commit in master, without needing special knowledge for manual workaround. thanks!

Piotr Sarnacki
Collaborator
drogus commented

@jrochkind I've already backported it, but before the release, you may include mounted helpers manually like that:

require 'test_helper'

class FooTest < ActionDispatch::IntegrationTest
  include Rails.application.routes.mounted_helpers

  test "foo" do
    puts blog.foo_path
  end
end
Jonathan Rochkind

@drogus, also, I use "ordinary" path helpers in ActionView::TestCase tests -- ordinary route path helpers work here, but isolated engine root path helpers do not.

Does your patch apply to ActionView::TestCase tests, or only other 'integration' tests?

Jonathan Rochkind

@drogus, ah, sorry, we're crossing streams. So i can presumably do the same include Rails.application.routes.mounted_helpers in an ActionView::TestCase rather than an ActionDispatch::IntegrationTest? And/or monkey patch that include into all ActionView::TestCases? I will try it!

Since 'standard' routing helpers are ordinarily available in ActionView::TestCase as well, suggest isolated engine mount route helpers should be as well, yes?

Piotr Sarnacki
Collaborator
drogus commented

@jrockind yup, I think that we could do the same, I wasn't aware that they're also included there, thanks for pointing that out!

Jonathan Rochkind

thanks @drogus, you're my hero for today.

Piotr Sarnacki
Collaborator
drogus commented

@jrochkind ok, they're actually not included there, but there are available on test controller that's used in those tests, fixed here: 60b4290, I need to run, I will backport it to 3-2-stable as well when I get back

Jonathan Rochkind

thanks again @drogus! Instructions for monkey patching a workaround into a current 3.2.x release (for ActionView::Test and it's test controller) would be much appreciated, otherwise I'll muddle through trying to reverse engineer your commit and get it eventually probably.

Erich Menge erichmenge referenced this issue from a commit in erichmenge/rails
Piotr Sarnacki Include routes.mounted_helpers into integration tests
In integration tests, you might want to use helpers from engines that
you mounted in your application. It's not hard to add it by yourself,
but it's unneeded boilerplate. mounted_helpers are now included by
default. That means that given engine mounted like:

    mount Foo::Engine => "/foo", :as => "foo"

you will be able to use paths from this engine in tests this way:

    foo.root_path #=> "/foo"

(closes #6573)
8d4f63a
Piotr Sarnacki
Collaborator
drogus commented

@jrochkind unfortunately it's not as easy as just including mounted helpers into your tests, so you can:

  def method_missing(selector, *args)
    if @controller.respond_to?(:_routes) &&
         @controller._routes.mounted_helpers.method_defined?(selector)
      @controller.__send__(selector, *args)
    else
      super
    end
  end

and use it as a superclass for your tests

  • add a module that you will include in tests where you need mounted helpers:
module MountedHelpersFix
  def method_missing(selector, *args)
    if @controller.respond_to?(:_routes) &&
         @controller._routes.mounted_helpers.method_defined?(selector)
      @controller.__send__(selector, *args)
    else
      super
    end
  end
end

class FooHelperTest < ActionView::TestCase
  include MountedHelpersFix

  # tests ...
end

I would probably do the third option if tests using mounted helpers are not the majority and the second one if you need it almost everywhere

SixArm

@drogus Can you explain more about your findings and how to do it the right way? I'm having the same issue and I will edit the Rails guides for engines to add your info, so others can see the right way to do it.

Saurabh Nanda

Hi, I ran into this issue today. We're having a really hard time figuring out the testing story around engines. Especially how they interact with the host application, routing, fixtures, and dependencies.

I used the monkey-patch given in this thread and it worked (although I monkey-patched ActionController::TestCase and not ActionView::TestCase as suggested here)

If this has still not been merged into the main Rails codebase, please consider this is as "vote" of some sorts to do so. We're on the Rails 3.1.x branch.

Steve Klabnik
Collaborator

@saurabhnanda please note that Rails 3.1 is getting no security fixes any more: http://weblog.rubyonrails.org/2013/2/24/maintenance-policy-for-ruby-on-rails/

Please upgrade to at least 3.2 as soon as possible.

Meck yesmeck referenced this issue in blowmage/minitest-rails-capybara
Closed

Inlcude routes.mounted_helpers #25

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.