Faking instance variable in RSpec and Capybara feature spec

2.3k views Asked by At

I'm trying to set up some feature specs before I get into refactoring some of my company's old code. It's kind of an unconventional setup, but I was able to figure out enough about test doubles to bypass the authentication enough to get started. One problem I'm still having is that some of the instance variables set in these methods I'm bypassing are expected by the view, so I get undefined method for nil:NilClass errors. I would like to get the specs running before I make any changes to the program code. In this case, I could easily just move the particular instance variable to another method. But I'm sure more situations like this will come up. Here's the example I'm currently working on:

def security_level
  @right_now = Time.now

  #
  # other code that wont work without
  # connecting to a remote authentication
  # server
  #

end

Then in my spec:

feature 'Navigation' do
  before(:each) do
    allow_any_instance_of(ApplicationController).to receive(:security_level).and_return(nil)
  end
  scenario 'is possible' do
    visit root_path
    expect(page.has_content?('Quick Stats'))
  end
end

Here's the error, coming from @right_now.year in the view

 Failure/Error: visit root_path
 NoMethodError:
   undefined method `year' for nil:NilClass
 # ./common/views/layouts/bootstrap/layout.haml:63

EDIT: Is there a way to set instance variables on the controller from within a feature spec?

2

There are 2 answers

2
Aaron K On BEST ANSWER

There's no easy way to accomplish what you want.

The feature spec is handled mostly by Capybara, not RSpec. Capybara runs the majority of the browser / rails server behavior in an external process. This make it inaccessible from RSpec's point-of-view. Thus you cannot use stubs / doubles in this manner.

Feature specs are largely meant to be end-to-end acceptance tests. The idea is to exercise your system as those who would use your system do. Generally, in these types of specs you perform various "workflows". This means, having the spec, log a user in, navigate to particular pages, filling forms, clicking buttons and links. You then generally make your expectations on what you see in the view.

This means your spec would look more like:

feature 'Navigation' do
  let(:regular_user) { User.create!(name: 'A Regular User') }

  def sign_in(a_user)
    visit sign_in_url
    # fill out form
    click_button 'Sign In'
  end

  before(:each) do
    sign_in(regular_user)
  end

  scenario 'is possible' do
    visit root_path
    expect(page.has_content?('Quick Stats'))
  end
end
0
Thomas Walpole On

https://github.com/per-garden/fakeldap may provide enough ldap functionality for your feature tests.