开发者

Testing with Rspec, NiftyAuthentication

I'm using Ryan Bates's nifty:authentication, and starting testing with Rspec. Fought with this for weeks, and still don't understand what's happening.

My controller simply calls

before_filter :login_required, :except => [:login]

Which is defined in lib/controller_authentication

def self.included(controller)
    controller.send :helper_method, :current_account, :logged_in?, :redirect_to_target_or_default
  end

  def current_account
    @current_account ||= Account.find(session[:account_id]) if session[:account_id]
  end

  def logged_in?
    current_account
  end

  def login_required
    unless logged_in?
      store_target_location
      redirect_to login_url, :alert => "You must first answer me these riddles three log in or sign up before accessing this page."
    end
  end

  def redirect_to_target_or_default(default, *args)
    redirect_to(session[:return_to] || default, *args)
    session[:return_to] = nil
  end

  private

  def store_target_location
    session[:return_to] = request.url
  end
end

The app works as intended, but the testing fails every time. No matter what I try, I get the redirect_to login_url, :alert => "You must first ...log in" page.

Things I've tried:

controller.stub!( :login_required )
ControllerAuthentication.stub!(:current_account).and_return(Account.where(:username => 'ej0c').first)
#ControllerAuthentication.stub!(:logged_in?).and_return(Account.where(:username => 'ej0c').first)
ControllerAuthentication.stub!(:login_required).and_return(true)
MyDigisController.stub!( :login_required ).and_return(true)

Which I think means I'm missing the whole theory of the thing. How can I make my login work?


I tried as Punit suggests below: [pre]

require 'spec_helper'

describe "View event details" do

  it "Should show a table of events" do
     @account = Accou开发者_运维问答nt.where(:username => 'ej0c').first
     puts @account.inspect
     controller.stub!(:current_account).and_return(@account)
     controller.stub!(:logged_in?).and_return(true)
     session[:account_id] = @account.id
      visit '/my_digis/66/custom_events'
      page.should have_content('Events')

  end
end

@account.inspect displayed nicely, but I also got

An expectation of :current_account was set on nil. Called from C:/Users/Ed/webapps/whendidji3/spec/con
.rb:8:in `block (2 levels) in <top (required)>'. Use allow_message_expectations_on_nil to disable warn
An expectation of :logged_in? was set on nil. Called from C:/Users/Ed/webapps/whendidji3/spec/controll
:in `block (2 levels) in <top (required)>'. Use allow_message_expectations_on_nil to disable warnings.

Thanks for any detailed explanations, as I've searched high an low to understand what's goin on.


You are using a vanilla spec rather than a controller spec, which means that the variable 'controller' is not being set.

To use a controller spec, you need to pass the controller class name to your describe block rather than a string.

describe MyController do

see http://rspec.info/rails/writing/controllers.html

Once you have that going, you should be able to use your original thought of stubbing login_required


You need to stub the "current_account" method. You could do it like this -

@account = create_account #function to create an account for your specs
controller.stub!(:current_account).and_return(@account)
controller.stub!(:logged_in?).and_return(true)

You should probably create a method out of the above lines to stub authentication wherever required.


OK, the answer was that I needed a request spec.

I'd begun with a request spec, but it wasn't in the requests folder, and the questions I asked got it morphed into a half-request/half-controller spec, none of which works.

The strange thing about rspec is that it will complain if a capybara method is badly formed,...but it won't mention that the thing just plain doesn't work where you put it!

My working spec, located in specs/requests/my_digis_spec.rb is

require 'spec_helper'

describe "MyDigis" do

   before :each do
@account = Account.where(:username => 'me').first
visit login_path
    fill_in 'Username or Email Address', :with => @account.email
    fill_in 'Password', :with => 'password'
  click_button('Log in')

end

it "Shows list of digis" do
  visit my_digis_path
  page.should have_content('Your Custom Event groups')
end

it "Lets you modify didji list" do
  visit my_digis_path
  click_button('Modify events')
  page.should have_content('Events for my_digi')
end

end

As easy as advertised, just took me 5 weeks to get the login part. Thanks.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜