h.some_route_path helper undefined in fast test but works in app #506

Closed
carols10cents opened this Issue Apr 1, 2013 · 12 comments

Projects

None yet

4 participants

Contributor

Hi all a' yinz on the draper team,

I'm using draper 1.1.0, minitest 4.5.0, rails 3.2.13, mocha 0.13.2, I can specify anything else you'd like if it would be helpful.

I'm trying to write a fast test for a method on my decorator that uses a url helper. This method works as I expect when used in the app, but when I run this test, I get:

undefined method `user_impersonation_path' for #<#<Class:0x007f8cf2ae1bf0>:0x007f8cf3fb0c98>

I've created a really minimal repo with the essential parts of my decorator, test, fast test helper, and gems: https://github.com/carols10cents/draper_bug

I saw this wiki page that looked sort of relevant, but I'm not using grape: https://github.com/drapergem/draper/wiki/Using-Rails-Path-Helpers-in-Draper-Decorators-with-Grape

I tried doing this:

Draper::ViewContext.test_strategy :fast do
  include Rails.application.routes.url_helpers
end

But then, clearly, it says it knows nothing about Rails because I don't want it to know about Rails :(

I'd love either recommendations on how to fix what I'm doing wrong (in which case I'd be happy to update documentation because I looked and couldn't find anything especially in the fast test section of the README), or confirmation that I found a bug. Thanks!!! ❤️ ❤️ ❤️

Owner

I just put out 1.2.0, can you give it a try?

Contributor

Yep, updated the Gemfile in carols10cents/draper_bug, I'm seeing the same result. I did a quick skim through the commits between 1.1.0 and 1.2.0 and didn't see anything immediately relevant looking...

Owner

Woot! Thanks. Just wanted to check.

Member
nashby commented Apr 1, 2013

Hrm, not sure how url helpers can work without rails :)

Contributor

@nashby is there a way that they can just not throw an error? is there a straightforward way i can stub them?

Contributor
haines commented Apr 1, 2013

@carols10cents yeah, stubbing them is the way forward. You can just set stubs on helpers (or h) directly because it is available in your tests:

it "uses url helpers" do
  helpers.stub user_impersonation_path: "user_impersonations/1"
  # ...
end

Obviously you could get a bit more fancy and set expectations on the argument passed to the path helper, but you get the idea!

Contributor

Actually, it doesn't look like I have access to helpers in the test, at least not when using test_strategy :fast.

I tried just accessing helpers in the test, and this got me NameError: undefined local variable or method 'helpers' for #<#<Class:0x007fcd53ec0338>:0x007fcd53ec6620>. See commit 8d523194f370bc3243fb1e465b10e6bbf10d5504.

I then tried following the instructions in the README to include ApplicationHelper with the test_strategy :fast like this:

Draper::ViewContext.test_strategy :fast do
  include ApplicationHelper
end

but I still get NameError: undefined local variable or method 'helpers' for #<#<Class:0x007fedb5c2d9e0>:0x007fedb5c3d070> when I try to access helpers. See commit 374c5ae1ddd1a6b4a63d11c29b99a5a8877bec64.

What am I doing wrong?

Contributor
haines commented Apr 2, 2013

Ah... since you're not using MiniTest::Rails, Draper doesn't realise that it needs to register decorator specs. Doing so makes them instances of Draper::TestCase, and once that happens you get the helpers method in your tests.

I think you need to manually require draper/test/minitest_integration to hook everything up.

Contributor

If I add require 'draper/test/minitest_integration' to my test, I now get the error message:

/Users/carolnichols/.rvm/gems/ruby-1.9.3-p327@draper_bug/gems/draper-1.2.0/lib/draper/test/minitest_integration.rb:2:in `<class:TestCase>': 
undefined method `register_spec_type' for Draper::TestCase:Class (NoMethodError)

See commit 0f83d79fae1e88193aef9ade985bdec51e1b261f

@steveklabnik steveklabnik reopened this Apr 2, 2013
Owner

I'm giving this a re-open, because at least I'd like to either support this better or document this process better.

Contributor
haines commented Apr 2, 2013

Ugh, ok, so minitest-rails has to extend the built-in Rails test case classes to add the spec DSL here. As you're on minitest 4.5.0, you can't just adapt that approach (unfortunately - the necessary module is a recent addition to minitest). This means that register_spec_type isn't going to work for you, so you'll have to ditch draper/test/minitest_integration - sorry for the red herring!

I think the simplest solution is just to manually include Draper::ViewHelpers in your spec, and stub away. Here are the changes needed to get your tests working (apologies also due for my RSpec mocks syntax earlier, which didn't work with Mocha!). Hope that works for you too!

Contributor

@haines thanks, that works great!!!! Also thanks for catching my multi-line bug :)

I've pulled your changes into my example repo and the test totally passes now. I've also successfully used this in my actual code. I'm going to work on a PR to update the documentation in the "Isolated Tests" part of the README.

@haines haines closed this Apr 14, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment