2014-02-06 165 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

相关问题