2012-08-16 40 views
0

的Rails 3.2.6Rspec的控制器測試失敗時零

我已經設置了聯繫控制器和形式這篇文章的建議: http://matharvard.ca/posts/2011/aug/22/contact-form-in-rails-3/

Message模型類:

class Message 
    include ActiveModel::Validations 
    include ActiveModel::Conversion 
    extend ActiveModel::Naming 

    attr_accessor :name, :email, :message_body 

    # validations are here... 

    def initialize(attributes = {}) 
     attributes.each do |name, value| 
     send("#{name}=", value) 
     end 
    end 

    def persisted? 
     false 
    end 
end 

The Contact Controller

def create 
    @message = Message.new(params[:message]) 

    if @message.valid? 
     ContactMailer.new_message(@message).deliver 
     redirect_to(root_path, :notice => "Message was successfully sent.") 
    else 
     render :new 
    end 
end 

我的RSpec的控制器測試:

describe "POST create" do 
    context "with valid information" do 
     let (:message) { FactoryGirl.build(:message) } 
     it "creates a new message" do 
     post :create, params: message 
     assigns(:message).should eq(message) 
    end 
    end 
end 

我已經通過let驗證了message變量不是零,所以FactoryGirl正在做的工作。

測試結果:

ContactController POST create with valid information creates a new message 
Failure/Error: post :create, params: message 
NoMethodError: 
    undefined method `each' for nil:NilClass 
# ./app/models/message.rb:14:in `initialize' 
# ./app/controllers/contact_controller.rb:8:in `new' 
# ./app/controllers/contact_controller.rb:8:in `create' 
# ./spec/controllers/contact_controller_spec.rb:22:in `block (4 levels) in <top (required)>' 

我知道它的失敗是因爲Messageinitialize方法。但我現在確定它爲什麼初始化爲零。當我在開發環境中測試表單時,它似乎工作正常。謝謝你的幫助。

+0

您似乎錯過了'it'塊中的'end'。 – Finbarr 2012-08-16 22:45:47

+0

當我將代碼粘貼到現在已更正的StackOverflow中時發生錯字。 – 2012-08-16 22:57:01

+0

我建議調試params [:message]的值 – Finbarr 2012-08-16 22:59:37

回答

0

我不得不將一個散列作爲值傳遞給post的散列選項。像這樣:

message_attributes = FactoryGirl.attributes_for(:message) 
post :create, message: message_attributes 

爲了測試兩個消息比較,我不得不修改Message模型像這樣:

attr_accessor :attributes, :name, :email, :message_body 
def initialize(attributes = {}) 
    if not attributes.nil? 
     attributes.each do |name, value| 
      send("#{name}=", value) 
     end 
    end 
    @attributes = attributes 
end 

所以最後一個經過測試是這樣的:

it "creates a new message" do 
    message_attributes = FactoryGirl.attributes_for(:message) 
    post :create, message: message_attributes 
    assigns(:message).attributes.symbolize_keys.should eq(message_attributes) 
end 

我不知道這是否是最佳的解決方案,但它確實創造通過的測試和驗證控制器正確地創建消息。

0

我想你應該將消息傳遞與它明確的名稱,就像這樣:

it "creates a new message" do 
    post :create, :message => message 
    assigns(:message).should eq(message) 
end 

或短期風格:

post :create, message: message 

,那麼你將有PARAMS哈希鍵'message'

params[:message] = ... # here's your message 

否則你不會有一個關鍵的params和hense params[:message]返回零

+0

這對我來說不起作用。看到我的答案。 – 2012-08-17 20:07:50

+0

我犯了一個錯誤,看到更新 – megas 2012-08-18 02:40:44

+0

這仍然不適合我。當我用這種方法嘗試時,@message被創建時沒有任何屬性。 – 2012-08-24 17:14:01