【问题标题】:Rspec Test Required parametersRspec 测试所需参数
【发布时间】:2013-04-18 08:39:13
【问题描述】:

我将 FactoryGirl 和 Rspec 用于我的测试框架。我有一个模型,上面有 validates_presence_of 验证。基本的 Rspec 框架包括一个测试:

describe "with invalid params" do
  it "assigns a newly created but unsaved disease as @disease" do
    # Trigger the behavior that occurs when invalid params are submitted
    Disease.any_instance.stub(:save).and_return(false)
    post :create, :disease => {}
    assigns(:disease).should be_a_new(Disease)
  end
end

编辑: diseases_controller.rb

 # POST /diseases
 # POST /diseases.xml
 def create
   @disease = Disease.new(disease_params)

   respond_to do |format|
     if @disease.save
       format.html { redirect_to(@disease, :notice => 'Disease was successfully created.') }
       format.xml  { render :xml => @disease, :status => :created, :location => @disease }
     else
       format.html { render :action => "new" }
       format.xml  { render :xml => @disease.errors, :status => :unprocessable_entity }
     end
   end
 end

 private
 def disease_params
   params.require(:disease).permit(:name, :omim_id, :description)
 end

此测试不适用于我的应用程序的工作方式。它不会在不正确的帖子上返回新疾病,而是返回错误:

Required parameter missing: disease

问题 #1:我不知道如何查看 Rspec 返回的内容。在这种情况下似乎没有创建 response 对象?打印assigns(:disease) 似乎不包含任何内容。我通过将 cURL 帖子提交到带有空数据的正确 URL 收到了我之前发布的错误消息(这是 rspect 帖子应该做的),但我不知道如何获取 Rspec 从那里收到的信息发表声明。

问题 #2:我如何正确测试应该发生的响应 - 它收到一条错误消息,指出缺少必需的参数?

编辑: 所以我的控制器似乎表明它应该呈现一种新的疾病,但测试失败了。如果我尝试在网站上提交缺少所需参数的疾病,那么它会发出一个快速通知,上面写着“名称不能为空”。我不确定如何在 rspec 中进行测试。

编辑#2: 包括上面的代码。 disease_params 根据使用strong_parameters gem 的建议在控制器底部定义。

谢谢!

【问题讨论】:

  • 你在哪里定义disease_params
  • 这里似乎失败了params.require(:disease),但我不知道为什么
  • 你有strong_parameters gem吗? params.require(:disease) 正在寻找类似于以下内容的哈希:Parameters: {"disease"=>{"name"=>"Disease 4", "omim_id"=>nil, "description"=>nil}}
  • 嗯...好吧,如果我将帖子更改为post :create, :disease => { :name => ''},那么测试成功...我不知道为什么。 '' 应该仍然没有通过 validates_presence_of 测试,对吧?
  • 您在任何疾病实例上存根 save,因此不会执行模型验证。

标签: ruby-on-rails rspec


【解决方案1】:

回答问题 1(“我不知道如何查看 Rspec 返回的内容”)...您可以在规范中使用“puts”语句(即在 it 块中)。例如,您可以尝试这样的操作:

describe "with invalid params" do
  it "assigns a newly created but unsaved disease as @disease" do
    # Trigger the behavior that occurs when invalid params are submitted
    Disease.any_instance.stub(:save).and_return(false)
    post :create, :disease => {}
    puts :disease
    assigns(:disease).should be_a_new(Disease)
  end
end

这是一个有价值的调试工具。当 RSpec 运行时,输出将在终端的 .s 和 Fs 中。

对于问题 2,我不太确定您在寻找什么,但我不知道您需要(或应该)测试无效疾病是否被指定为 @disease。我倾向于按照以下样式编写控制器规范(取自Everyday Rails Testing with RSpec,这是我学习如何编写控制器规范的地方)。

POST 创建规范示例:

context "with invalid attributes" do
  it "does not save the new contact" do
    expect{
      post :create, contact: Factory.attributes_for(:invalid_contact)
    }.to_not change(Contact,:count)
  end

  it "re-renders the new method" do
    post :create, contact: Factory.attributes_for(:invalid_contact)
    response.should render_template :new
  end
end 
...

您可能有理由更彻底地测试我不知道的控制器方法。在这种情况下,请忽略我对问题 2 的回答,希望我的其他回答有用!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-07
    相关资源
    最近更新 更多