Rails 3.2.6
我按照本文的建议设置了一个Contact Controller和表单: 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
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
我已通过message
验证let
变量不是零,因此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)>'
由于Message
的{{1}}方法,我知道它失败了。但我现在肯定为什么它正在初始化为零。当我在开发环境中测试表单时,它似乎工作正常。谢谢你的帮助。
答案 0 :(得分:0)
我认为您应该使用明确的名称传递消息,如下所示:
it "creates a new message" do
post :create, :message => message
assigns(:message).should eq(message)
end
或短款式:
post :create, message: message
那么你将在params hash中有一个键'message'
params[:message] = ... # here's your message
否则,params
中没有密钥,而params[:message]
返回的密钥为
答案 1 :(得分: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
我不确定这是否是最佳解决方案,但它确实会创建一个通过测试并验证控制器是否正确地创建了一条消息。