1

I am trying to stub Spree's current_user method in Rspec 3.0, Capybara 2.3, to no avail. My goal is to test the page for content that should only appear when the user is logged in. How can I stub the spree_current_user helper in a feature spec?

Feature Spec

#spec/features/spree_variants_spec.rb
before(:each) do
  user = FactoryGirl.create(:user, first_name: "First name")
  helper.stub :spree_current_user => user # does not work
end

Controller

class Designers::SpreeVariantsController < ApplicationController
  def create
    ...
    @variant.attribute  = spree_current_user.first_name  #line 14
    ...
  end
end

Error

Failure/Error: click_button 'Create'
 NoMethodError:
   undefined method `first_name' for nil:NilClass
 # ./app/controllers/designers/spree_variants_controller.rb:14:in `create'

In stubbing the method, I have also tried:

#2
Designers::SpreeVariantsController.stub :spree_current_user => instance_double(Spree.user_class, :has_spree_role? => true, :last_incomplete_spree_order => nil, :spree_api_key => 'fake', first_name: "First name")

#3
self.stub :spree_current_user => user # same error

#4
helper.stub :spree_current_user => user # does not recognize 'helper'
Dave Schweisguth
  • 36,475
  • 10
  • 98
  • 121
steel
  • 11,883
  • 7
  • 72
  • 109

1 Answers1

2

RSpec's request and feature specs are designed for testing the full stack, not individual controllers, so you can't get an instance of a controller. It might meet your needs to stub the method on all instances of that controller:

allow_any_instance_of(Designers::SpreeVariantsController).to receive(:spree_current_user).and_return(user)

However,

  • according to the RSpec documentation, request specs don't support current versions of Capybara. If it's working for you in request specs, so far so good, but you may be going down a deprecated path. The up-to-date way of writing specs that exercise your entire stack is feature specs.

  • Request specs and feature specs are for testing the entire stack, not unit testing. Stubbing in them is a little fishy. You should consider writing a few request or feature specs in which the user logs in through the UI, and testing details in controller specs where you should feel free to stub whatever you like.

Dave Schweisguth
  • 36,475
  • 10
  • 98
  • 121
  • Ah. Well I'm not so far down the road that I can't switch it over to feature specs, thanks. What I'm looking to do is test for certain content on the page, based on whether or not the user is signed in (and has a certain role, ideally). I was only attempting to stub the controller in desperation. What's the right way to appear logged in to a feature spec in spree? – steel Aug 08 '14 at 17:06
  • You know what, I'm confusing myself at this point. You answered my question well here, thank you. I'm going to reorganize my thoughts, as it appears I have two different questions here. Thank you. – steel Aug 08 '14 at 17:17
  • I think you're right. Nonetheless: you wouldn't *appear* logged in, you'd actually log in. Don't know the exact values, but something vaguely like `visit some_path; fill_in 'username', with: 'the_username'; fill_in 'password', with: 'the_password'`; click_button 'Log in'. – Dave Schweisguth Aug 08 '14 at 17:23
  • Well that changes the whole approach to my second issue. Thanks, I'll look down that path. – steel Aug 08 '14 at 17:28