Cucumber/webrat, need to set user in session, can't stub or mock. Fixtures?

Hi – I’m assuming that there are excellent reasons for not enabling
stubs &
mocks in cucumber, but I find myself in a bit of a pickle without them.
Basically, I want to write a feature that has the home page displaying
if
there is a logged in user (identified by a call to current_user, which
in
turn checks session[:user_id]), and that displays an unauthorised access
page if there isn’t.
I guess normally, I’d have webrat walk through my app, including logging
in?
Unfortunately, the login doesn’t happen in this application, though. It
happens in another that shares state with this one, so I can’t do this.
Could someone advise how I can set up my scenario so that there is a
valid
user either in the session, or stubbed from the current_user?
Would this be something to do with fixtures?
If so, could someone point me at some docs that show me how to use them
with
cucumber?
Thanks for any & all help,
Doug.

On Mon, Apr 27, 2009 at 3:09 PM, doug livesey [email protected] wrote:

Hi – I’m assuming that there are excellent reasons for not enabling stubs &
mocks in cucumber, but I find myself in a bit of a pickle without them.

Aslak and I were discussing this very thing earlier today. There are
definitely good reasons not to use message expectations (mocks - see
http://wiki.github.com/aslakhellesoy/cucumber/mocking-with-cucumber)
in cucumber, but stubs are different and we’re thinking there should
be support for them.

I haven’t tried this, but you should be able to do what RSpec does to
adapt to different mock/stub frameworks. To use rspec’s, for example,
you should be able to say:

require ‘spec/mocks/framework’
require ‘spec/mocks/extensions’

World(Spec::Mocks::ExampleMethods)

Before do
$rspec_stubs ||= Spec::Mocks::Space.new
end

After do
$rspec_stubs.reset_all
end

Now you should have the same mocking/stubbing methods you do in
rspec examples in cucumber step definitions, and the stubs get cleared
out after each scenario. See if that works, and then maybe we can
figure out a way to generalize rspec’s mock-framework-adapter
framework so cucumber can use it as well (so you’d be able to stub w/
mocha, rr, flexmock, or any other).

Cheers,
David

Cheers for that – I’ll give it a try.
Would all of that be in the step file?
(Total cucumber newbie, sorry!)
Cheers,
Doug.

On Mon, Apr 27, 2009 at 3:39 PM, doug livesey [email protected] wrote:

Cheers for that – I’ll give it a try.
Would all of that be in the step file?

Please be sure to clip the relevant parts when responding - “all of
that” is only meaningful if I look at the other email in this thread.
Easy on my desk top. Not so easy on my phone.

Try support/env.rb.

Cheers,
David

Please be sure to clip the relevant parts when responding - “all of
that” is only meaningful if I look at the other email in this thread.
Easy on my desk top. Not so easy on my phone.

Bit too used to gmail threads, sorry!
Doug.

Except I’m now struggling with how it should work, sorry.
The step for the scenario looks like this:

Given /^that a user is logged in to the session$/ do
controller.stub!( :current_user ).and_return( true )
end

However, when I try to puts the value of current_user as called from the
ApplicationController#authorise method, it returns nil.
I’ve tried just stubbing out the authorise method, too, but that doesn’t
seem to work, either.
Am I approaching this the wrong way?
& cheers again,
Doug.

2009/4/27 doug livesey [email protected]

& that nailed it, cheers man!
Doug.

2009/4/27 doug livesey [email protected]

On Mon, Apr 27, 2009 at 5:24 PM, doug livesey [email protected] wrote:

User.stub!( :find ).and_return( true )
end

You probably want to return a User, no? Returning true is entirely
different than the normal find API w/ActiveRecord. It seems to be
misleading and I can see where it would cause problems where
controller or view code that relies on #current_user expects a User,

controller.stub!( :current_user ).and_return( true )
2009/4/27 doug livesey [email protected]

Bit too used to gmail threads, sorry!
Doug.


rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users


Zach D.
http://www.continuousthinking.com (personal)
http://www.mutuallyhuman.com (hire me)
@zachdennis (twitter)

Yeah, I take your point, but I would need to set that up with fixtures,
wouldn’t I?
& really I guess I should be seeding the session with a User id &
letting
all of the code do its work, not just stubbing the find method on
ActiveRecord.
I’ll have a think on it – for the moment it’s quick & uncomplicated,
and I
think that current_user returning true is fairly self-explanatory –
maybe
returning :a_logged_in_user would be less evil.
& my attitude there might have more to do with the time here being a
half-hour off of midnight than conscientiousness! :wink:
Doug.

2009/4/27 Zach D. [email protected]

Further to this, here is what I am currently doing.
I installed the seed-fu plugin and wrote a method in my env.rb file like
this:

Load fixtures by tableised names.

def seed_fixtures( *fixtures )
ActiveRecord::Base.establish_connection(
ActiveRecord::Base.configurations[‘test’] )
ActiveRecord::Schema.verbose = false

fixtures.each do |fixture|
load( File.join( RAILS_ROOT, “db/fixtures/test”, “#{ fixture }.rb” )
)
end
end

So in any Given that requires my fixtures, I can call “seed_fixture
:my_first_models, :my_second_models” to load up anything I need for my
cucumber steps.
And the examle above called “seed_fixtures :users”, and returned a user,
not
just a true value.
Cheers,
Doug.

2009/4/27 doug livesey [email protected]

Refactoring the current_user method a little, then stubbing the find
method
in there did it.

ApplicationController

def current_user
User.find( session[:user_id] ) rescue nil
end

Scenario step

Given /^that a user is logged in to the session$/ do
User.stub!( :find ).and_return( true )
end

Cheers,
Doug.

2009/4/27 doug livesey [email protected]

Bookmarked for later research – cheers for pointing that out!

2009/4/29 Chris F. [email protected]

I have a subapp that authenticates remotely, and pulls information from
the
main app using ActiveResource, and a token provided in a cookie, which
sounds at least close to what you’re trying to test

While it’s possible to stub the values coming back, it can be tricky.
By
definition, you pretty much don’t have access to the exact instance of a
controller class, so stubbing controller.current_user just won’t work

plus, that exercises pretty much none of the authentication code.

What I’ve taken too lately is making sure that my authentication code is
really well separated, even from my ActiveResource model. at that
point, in
my integration tests, I drop a stub object into the authentication code,
in
place of the Active Resource, and my Givens set up return values for
that
stub object … (stub in the it’s a fake sense, not stub in the literal
RSpec object sense)

All that said, a couple of days ago, I caught wind of this little gem:
http://fakeweb.rubyforge.org/ (and, of course, I can’t remember who
pointed
it out … might have been someone on this list, might have been someone
on
twitter …)
It looks like it cuts directly in front of the core HTTP library, and
lets
you register fake responses to the request. Using that, can probably
just
skip the above, and fake a response from the remote system … acutally
leaving the ActiveResource model in the system, and therefore,
tested…
Just havn’t had that chance yet