Mocking and accessing Controller instance in Cucumber

554 views
Skip to first unread message

quicksilver-fan-on-linux

unread,
Feb 25, 2011, 3:20:03 PM2/25/11
to Cukes
Yeah I know having Mocking and Cucumber in the same sentence is a sin,
but sometime practicality trumps theory.

I have a 3rd party service that gets called in the controller. This
service is not reliable/reachable in the test environment, hence the
need to mock the call from controller to this service.

Here is what I have tried

Approach 1:
in support/env.rb I have the following

Before do
# To get RSpec stubs and mocks working.
$rspec_mocks ||= Spec::Mocks::Space.new
end

After do
begin
$rspec_mocks.verify_all
ensure
$rspec_mocks.reset_all
end
end

in step definition I have

When /^(?:|I )press "([^"]*)"(?: within "([^"]*)")?$/ do |button,
selector|
@controller.should_receive(:sync_account_to_ldap)
with_scope(selector) do
click_button(button)
end
end

when the test is run ... @controller is nil

Approach 2: using RR framework, obviously the controller is not
accessible but for now lets see RR cucumber approach

in env.rb

#apart from the Before After block described earlier following line is
added
require "spec/spec_helper" # this calls config.mock_with :rr

in step definition

When /^(?:|I )press "([^"]*)"(?: within "([^"]*)")?$/ do |button,
selector|
mock(controller).sync_account_to_ldap.with_any_args
mock(controller).sync_user_to_ldap.with_any_args
mock(controller).sync_account_to_salesforce.with_any_args
controller.should_receive(:sync_user_to_ldap)
controller.should_receive(:sync_account_to_salesforce)
with_scope(selector) do
click_button(button)
end
end

when test is run I get

undefined method `mock' for #<Cucumber::Rails::World:0x82717b04>

so in env.rb I add the following line

require 'rr'
Cucumber::Rails::World.send(:include, RR::Adapters::RRMethods)

now when the test is run controller is still nil

So I haven't figured out a way to get access to controller in Cucumber
step definitions.

Any help ?

-daya


Jonas Nicklas

unread,
Feb 26, 2011, 4:48:19 AM2/26/11
to cu...@googlegroups.com, quicksilver-fan-on-linux
Are you using Webrat or Capybara? If you're using Capybara you're not
going to be able to access the controller like this anyway. I'd
suggest looking into something like WebMock or VCR for mocking out the
service.

/Jonas

> --
> 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.
>
>

Craig Demyanovich

unread,
Feb 26, 2011, 10:33:03 AM2/26/11
to cu...@googlegroups.com, quicksilver-fan-on-linux
I recently worked on a feature that placed data on a queue when a resource was created/updated. I created a ResourceNotifier for two reasons: (1) to ensure that any changes to the queue caused changes in only one place in the app, and (2) to be able to easily stub/mock out the notifier in both specs and scenarios. Similarly, you could create an AccountSync class such as

class AccountSync
  def self.sync(...)
     # implementation here
  end
end

Then it becomes very easy to stub/mock in specs, and you could create a stub implementation that scenarios use to avoid doing a full sync over LDAP. Perhaps this AccountSyncStub just writes data to a file or to something in memory that you verify in your scenarios. And, if you want to change the sync in the future, you only have to change the implementation of this one class or write new subclasses and use those. None of your other code has to change.

Regards,
Craig

Jonas Nicklas

unread,
Feb 26, 2011, 11:10:45 AM2/26/11
to cu...@googlegroups.com, quicksilver-fan-on-linux
You might also consider actually running a local LDAP server. I don't
think that's too difficult to set up and you'd be making your tests a
lot more reliable.

/Jonas

On Fri, Feb 25, 2011 at 9:20 PM, quicksilver-fan-on-linux
<daya....@gmail.com> wrote:

Matt Wynne

unread,
Feb 28, 2011, 1:20:53 PM2/28/11
to cu...@googlegroups.com, quicksilver-fan-on-linux

Right on Craig. People seem to forget the difference between mocks and stubs. You really don't need a mock object in an acceptance test, but you might need a stub. And you don't need a mocking framework to create a stub. If you do, you've probably got a design problem you want to rectify anyway.

>
> --
> 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.

cheers,
Matt

ma...@mattwynne.net
07974 430184

Reply all
Reply to author
Forward
0 new messages