Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails: test a helper that needs access to the Rails environment (e.g. request.fullpath)

I have a helper that accesses request.fullpath. Within an isolated helper test, request is not available. What should I do? Can I somehow mock it or something like that?

I'm using the newest versions of Rails and RSpec. Here's what my helper looks like:

def item(*args, &block)
  # some code

  if request.fullpath == 'some-path'
    # do some stuff
  end
end

So the problematic code line is #4 where the helper needs access to the request object which isn't available in the helper spec.

Thanks a lot for help.

like image 728
Joshua Muheim Avatar asked Sep 21 '12 09:09

Joshua Muheim


1 Answers

Yes, you can mock the request. I had a whole long answer here describing how to do that, but in fact that's not necessarily what you want.

Just call your helper method on the helper object in your example. Like so:

describe "#item" do
  it "does whatever" do
    helper.item.should ...
  end
end

That will give you access to a test request object. If you need to specify a specific value for the request path, you can do so like this:

before :each do
  helper.request.path = 'some-path'
end

Actually, for completeness, let me include my original answer, since depending on what you're trying to do it might still be helpful.

Here's how you can mock the request:

request = mock('request')
controller.stub(:request).and_return request

You can add stub methods to the returned request similarly

request.stub(:method).and_return return_value

And alternative syntax to mock & stub all in one line:

request = mock('request', :method => return_value)

Rspec will complain if your mock receives messages that you didn't stub. If there's other stuff Just call your request helper method on the helper object is doing that you don't care about in your test, you can shut rspec up by making the mock a "null object",example. like Like so

 request = mock('request').as_null_object

It looks like all you probably need to get your specific test passing is this:

describe "#item" do
  let(:request){ mock('request', :fullpath => 'some-path') }

  before :each do
    controller.stub(:request).and_return request
  end

  it "does whatever"
end
like image 73
gregates Avatar answered Nov 03 '22 00:11

gregates