2014-02-06 127 views
2

已經給出了找出爲什麼一些rspec測試失敗的任務。我沒有編寫任何代碼,並且陷入困境。這裏是出放:當模型有效時,PeopleController創建操作應該重定向

3) PeopleController create action should redirect when model is valid 
    Failure/Error: post :create 
    TypeError: 
     no implicit conversion of nil into String 
    # ./app/models/person.rb:24:in `digest' 
    # ./app/models/person.rb:24:in `hexdigest' 
    # ./app/models/person.rb:24:in `encrypt_password' 
    # ./app/models/person.rb:30:in `prepare_password' 
    # ./app/controllers/people_controller.rb:10:in `create' 
    # ./spec/controllers/people_controller_spec.rb:20:in `block (2 levels) in <top (required)>' 

這裏是people_controller_spec:

require File.dirname(__FILE__) + '/../spec_helper' 

describe PeopleController do 
    fixtures :all 
    render_views 

    it "new action should render new template" do 
    get :new 
    response.should render_template(:new) 
    end 

    it "create action should render new template when model is invalid" do 
    Person.any_instance.stub(:valid?).and_return(false) 
    post :create 
    response.should render_template(:new) 
    end 

    it "create action should redirect when model is valid" do 
    Person.any_instance.stub(:valid?).and_return(true) 
    post :create 
    response.should redirect_to(root_url) 
    session['person_id'].should == assigns['person'].id 
    end 

    it "show action should redirect when not logged in" do 
    get :show, :id => "ignored" 
    response.should redirect_to(login_url) 
    end 

    it "show action should render show template" do 
    @controller.stub(:current_user).and_return(Person.first) 
    get :show, :id => "ignored" 
    response.should render_template(:show) 
    end 

end 

這裏是代碼塊,其中它的失敗people_controller:

def create 
    @person = Person.new(:username => params[:username], :password => params[:password], :first_name => params[:first_name], :last_name => params[:last_name]) 
    if @person.save 
     session[:person_id] = @person.id 
     if Invite.where(:ad_username => @person.username).count != 0 
     organization = Organization.find(Invite.where(:ad_username => @person.username).first.organization_id) 
     Affiliation.create!(:organization_id => organization.id, :person_id => @person.id, :affiliation_type => Affiliation::ATHLETIC_DIRECTOR) 
     end 
     redirect_to root_url, :notice => "Thank you for signing up! You are now logged in." 
    else 
     render :action => 'new' 
    end 
    end 

這裏是人模式:

class Person < ActiveRecord::Base 

    # new columns need to be added here to be writable through mass assignment 
    attr_accessible :username, :password, :password_confirmation, :first_name, :last_name, :cell_phone 
    has_one :affiliation, :dependent => :destroy 
    has_many :contacts, :dependent => :destroy 

    before_save :prepare_password 
    before_validation :downcase_username 

    validates :username, :uniqueness => {:case_sensitive => false} 
    validates_presence_of :username, :first_name, :last_name 
    validates_format_of :username, :with => /^[-a-z0-9_+\.]+\@([-a-z0-9]+\.)+[a-z0-9]{2,4}$/i, :message => " must be a valid email" 
    validates_presence_of :password, :on => :create 
    validates_confirmation_of :password 
    validates_length_of :password, :minimum => 4 

    def self.authenticate(login, pass) 
    person = find_by_username(login.downcase) 
    return person if person && person.password == person.encrypt_password(pass) 
    end 

    def encrypt_password(pass) 
    Digest::SHA1.hexdigest(pass) 
    end 

    private 

    def prepare_password 
    self.password = encrypt_password(password) 
    end 

    def downcase_username 
    self.username = self.username.downcase if self.username.present? 
    end 

end 

我不知道這是越來越絆倒。

回答

2

錯誤是由無:密碼造成的。看起來像before_save:prepare_password過濾器正在運行並拋出該錯誤。但是使用before_save似乎是不正確的,因爲每次更新時都會發生這種情況,每次都要重新加密密碼。將其更改爲before_create,以便它只發生一次。如果仍然引發錯誤,你可以做幾件事情要解決它,無論是:

def encrypt_password(pass) 
    Digest::SHA1.hexdigest(pass.to_s) # will change nils into strings and this won't blow up 
end 

或在您的測試用例添加密碼PARAM:

it "create action should render new template when model is invalid" do 
    Person.any_instance.stub(:valid?).and_return(false) 
    post :create, :password => "" # invalid password 
    response.should render_template(:new) 
end 

這樣的控制器將獲得params[:password]和將字符串傳入Person.new

相關問題