Sinatra method stubbing

42 views
Skip to first unread message

l.me...@tu-bs.de

unread,
Nov 26, 2009, 3:37:37 AM11/26/09
to Cukes
Since I know that stubbing should be avoided were possible for
cucumber, I need to simply stub out my "logged_in?" method to work
around the problem with sessions not being persisted across requests.

How do I stub out an instance method of a Sinatra::Application form
within a Cucumber step (or in a Hook). Where to I get access to the
application instance. Currently I can only find the "app" instance
variable of the world, which returns my Application's class but not
the current Instance.

Any suggestions?

Jeroen van Dijk

unread,
Nov 26, 2009, 4:54:14 AM11/26/09
to cu...@googlegroups.com

You are right. Stubbing should be avoided because you are doing an integration test. This means that there shouldn't be any stub whatsoever.

Instead, what you should do is actually perform the login action. So in your feature you would have something like:

Given I am logged in as admin
Then do whatever you want
....

And a step something like:

Given /^I am logged in as (.+) $/ do |user|
   User.create!(:name => user, password => 'secret')
   visit login_path
   fill_in('login', :with => user)
   fill_in('password', :with => 'secret')
   click_button("submit)
   # now your logged in as a user!
end

Hope this helps.

Cheers,
Jeroen

 

--

You received this message because you are subscribed to the Google Groups "Cukes" group.
To post to this group, send email to cu...@googlegroups.com.
To unsubscribe from this group, send email to cukes+un...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/cukes?hl=en.



aslak hellesoy

unread,
Nov 26, 2009, 5:03:25 AM11/26/09
to cukes
On Thu, Nov 26, 2009 at 10:54 AM, Jeroen van Dijk
<jeroentj...@gmail.com> wrote:
>
>
> On Thu, Nov 26, 2009 at 9:37 AM, l.me...@tu-bs.de <l.me...@tu-bs.de>
> wrote:
>>
>> Since I know that stubbing should be avoided were possible for
>> cucumber, I need to simply stub out my "logged_in?" method to work
>> around the problem with sessions not being persisted across requests.
>>
>> How do I stub out an instance method of a Sinatra::Application form
>> within a Cucumber step (or in a Hook). Where to I get access to the
>> application instance. Currently I can only find the "app" instance
>> variable of the world, which returns my Application's class but not
>> the current Instance.
>>
>> Any suggestions?
>
> You are right. Stubbing should be avoided because you are doing an
> integration test. This means that there shouldn't be any stub whatsoever.
>

It depends. I'm developing a Rails app right now that uses OpenID and
OAuth, and we're stubbing out all the network traffic with Fakeweb for
our Cucumber scenarios. (We also have scenarios that simulate network
failure, failed login and denied authorisation).

We could have used Watir or something to do a true end-to-end with the
external provider (Google), but decided it was more pragmatic to stub
it out and do some manual tests to verify that things were working
without stubs.

Aslak

aslak hellesoy

unread,
Nov 26, 2009, 5:03:43 AM11/26/09
to cukes
On Thu, Nov 26, 2009 at 10:54 AM, Jeroen van Dijk
<jeroentj...@gmail.com> wrote:
>
>
> On Thu, Nov 26, 2009 at 9:37 AM, l.me...@tu-bs.de <l.me...@tu-bs.de>
> wrote:
>>
>> Since I know that stubbing should be avoided were possible for
>> cucumber, I need to simply stub out my "logged_in?" method to work
>> around the problem with sessions not being persisted across requests.
>>
>> How do I stub out an instance method of a Sinatra::Application form
>> within a Cucumber step (or in a Hook). Where to I get access to the
>> application instance. Currently I can only find the "app" instance
>> variable of the world, which returns my Application's class but not
>> the current Instance.
>>
>> Any suggestions?
>
> You are right. Stubbing should be avoided because you are doing an
> integration test. This means that there shouldn't be any stub whatsoever.
>

It depends. I'm developing a site right now that uses OpenID and
OAuth, and we're stubbing out all the network traffic with Fakeweb for
our Cucumber scenarios. (We also have scenarios that simulate network
failure).

We could have used Watir or something to do a true end-to-end with the
external provider (Google), but decided it was more pragmatic to stub
it out and do some manual tests to verify that things were working

Jeroen van Dijk

unread,
Nov 26, 2009, 5:26:54 AM11/26/09
to cu...@googlegroups.com
On Thu, Nov 26, 2009 at 11:03 AM, aslak hellesoy <aslak.h...@gmail.com> wrote:
On Thu, Nov 26, 2009 at 10:54 AM, Jeroen van Dijk
<jeroentj...@gmail.com> wrote:
>
>
> On Thu, Nov 26, 2009 at 9:37 AM, l.me...@tu-bs.de <l.me...@tu-bs.de>
> wrote:
>>
>> Since I know that stubbing should be avoided were possible for
>> cucumber, I need to simply stub out my "logged_in?" method to work
>> around the problem with sessions not being persisted across requests.
>>
>> How do I stub out an instance method of a Sinatra::Application form
>> within a Cucumber step (or in a Hook). Where to I get access to the
>> application instance. Currently I can only find the "app" instance
>> variable of the world, which returns my Application's class but not
>> the current Instance.
>>
>> Any suggestions?
>
> You are right. Stubbing should be avoided because you are doing an
> integration test. This means that there shouldn't be any stub whatsoever.
>

It depends. I'm developing a site right now that uses OpenID and
OAuth, and we're stubbing out all the network traffic with Fakeweb for
our Cucumber scenarios. (We also have scenarios that simulate network
failure).

We could have used Watir or something to do a true end-to-end with the
external provider (Google), but decided it was more pragmatic to stub
it out and do some manual tests to verify that things were working


Agreed. So this discusion might be relevant as well then:

http://groups.google.com/group/cukes/browse_thread/thread/524e0f0bdd74e577/82d135af13429eb5

And as for stubbing, if you really need to, what you could do is reopen the class with the login method in your env.rb (after the sinatra code has been loaded) and do something like (I'm not too familiar with how Sinatra works here):

class YourClass
  def logged_in?
     true
  end
end

If this is just for one scenario you might want to use before and after hooks. See this blog post: http://www.brynary.com/2009/2/3/cucumber-step-definition-tip-stubbing-time

In this case I would do something like

require "spec/mocks"

Before('@logged_in')
  $rspec_mocks ||= Spec::Mocks::Space.new
  YourClass.stub!(:logged_in?).and_return(true)
end

After('@logged_in') do
  begin
    $rspec_mocks.verify_all
  ensure
    $rspec_mocks.reset_all
  end
end

You would need to add the @logged_in to your scenario ( http://wiki.github.com/aslakhellesoy/cucumber/tags )

Disclaimer: I haven't tested any of the above code so I'm not sure if it (still) works, but it should get you further I hope.

Jeroen
 

Lennart Melzer

unread,
Nov 26, 2009, 6:22:28 AM11/26/09
to cu...@googlegroups.com
Thanks for the suggestions, I ended up doing it like you described (reopening my application class and overriding those methods, see http://stackoverflow.com/questions/1800333/stubbing-sinatra-helper-in-cucumber)

I am doing my integration test using Webrat (should ahve mentioned that before, sorry)

I would loved to use the login action from outside (post to /auth in my case) but the problem is the session handling. The session isn't persisted that way subsequent requests to protected actions will fail since I am not logged in anymore.  this seems to be a known problem (http://github.com/erikpukinskis/sinatra-webrat-session-test)

So if you have a solution for this, I'd love to skip the workaround and perform the login action "for real".

greetings,

Lennart

Jeroen van Dijk

unread,
Nov 26, 2009, 6:35:08 AM11/26/09
to cu...@googlegroups.com
On Thu, Nov 26, 2009 at 12:22 PM, Lennart Melzer <l.me...@tu-bs.de> wrote:
Thanks for the suggestions, I ended up doing it like you described (reopening my application class and overriding those methods, see http://stackoverflow.com/questions/1800333/stubbing-sinatra-helper-in-cucumber)

I am doing my integration test using Webrat (should ahve mentioned that before, sorry)

I would loved to use the login action from outside (post to /auth in my case) but the problem is the session handling. The session isn't persisted that way subsequent requests to protected actions will fail since I am not logged in anymore.  this seems to be a known problem (http://github.com/erikpukinskis/sinatra-webrat-session-test)

So if you have a solution for this, I'd love to skip the workaround and perform the login action "for real".

You might want to try out http://github.com/jnicklas/capybara instead of webrat

This is a similar framework as webrat (although new, see posts from a couple of days ago), but it works on the rack level so it might workout better for you since you are using sinatra. The dsl is supposed to be compatible with webrat.

Haven't tried it out yet, but the first reactions were positive. Please let us know if you go this route and how it goes.

Jeroen



 

Ben Lovell

unread,
Nov 26, 2009, 7:30:13 AM11/26/09
to cu...@googlegroups.com
2009/11/26 Jeroen van Dijk <jeroentj...@gmail.com>


On Thu, Nov 26, 2009 at 12:22 PM, Lennart Melzer <l.me...@tu-bs.de> wrote:
Thanks for the suggestions, I ended up doing it like you described (reopening my application class and overriding those methods, see http://stackoverflow.com/questions/1800333/stubbing-sinatra-helper-in-cucumber)

I am doing my integration test using Webrat (should ahve mentioned that before, sorry)

I would loved to use the login action from outside (post to /auth in my case) but the problem is the session handling. The session isn't persisted that way subsequent requests to protected actions will fail since I am not logged in anymore.  this seems to be a known problem (http://github.com/erikpukinskis/sinatra-webrat-session-test)

So if you have a solution for this, I'd love to skip the workaround and perform the login action "for real".

You might want to try out http://github.com/jnicklas/capybara instead of webrat

This is a similar framework as webrat (although new, see posts from a couple of days ago), but it works on the rack level so it might workout better for you since you are using sinatra. The dsl is supposed to be compatible with webrat.

Haven't tried it out yet, but the first reactions were positive. Please let us know if you go this route and how it goes.

Jeroen


Just an FYI that webrat has an adapter for rack too. In fact it is the recommended approach when testing Sinatra apps. The old sinatra approach has been deprecated in favour of this.

Cheers,
Ben

Jonas Nicklas

unread,
Nov 26, 2009, 7:39:07 AM11/26/09
to cu...@googlegroups.com
Capybara should work very well with Sinatra. In fact, the Capybara
test suite uses a Sinatra application to run its tests against.

/Jonas

On Thu, Nov 26, 2009 at 12:35 PM, Jeroen van Dijk

Matt Wynne

unread,
Nov 26, 2009, 1:04:44 PM11/26/09
to cu...@googlegroups.com

On 26 Nov 2009, at 12:30, Ben Lovell wrote:

> Just an FYI that webrat has an adapter for rack too. In fact it is
> the recommended approach when testing Sinatra apps. The old sinatra
> approach has been deprecated in favour of this.


Is that deprecation in the webrat gem or just the HEAD from brynary's
github?

cheers,
Matt

http://mattwynne.net
+447974 430184

Ben Lovell

unread,
Nov 26, 2009, 1:08:25 PM11/26/09
to cu...@googlegroups.com
2009/11/26 Matt Wynne <ma...@mattwynne.net>


On 26 Nov 2009, at 12:30, Ben Lovell wrote:

> Just an FYI that webrat has an adapter for rack too. In fact it is
> the recommended approach when testing Sinatra apps. The old sinatra
> approach has been deprecated in favour of this.


Is that deprecation in the webrat gem or just the HEAD from brynary's
github?

cheers,
Matt

Since back in the day:

== 0.5.0 / 2009-08-12

* Major enhancements

  * Depreacate :rack_test and :sinatra in favor of :rack, which uses Rack::Test (Simon Rozet)

Cheers,
Ben

Reply all
Reply to author
Forward
0 new messages