Rspec测试所需参数

3

我正在使用FactoryGirl和Rspec作为我的测试框架。我有一个模型,其中包含一个验证是否存在的验证。基本的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

Edit: 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)似乎没有包含任何内容。我通过向正确的URL提交空数据(这是rspect post应该做的),得到了我之前发布的错误消息,但我不知道如何获取Rspec从post语句接收的信息。

问题2:我该如何正确地测试应该发生的响应——它会收到一个错误消息,说缺少一个必需的参数?

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

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

谢谢!


你在哪里定义 disease_params - apneadiving
似乎在这里失败了 params.require(:disease),但我不知道原因。 - apneadiving
你有使用 strong_parameters gem 吗?params.require(:disease) 要求一个看起来像这样的哈希值:Parameters: {"disease"=>{"name"=>"Disease 4", "omim_id"=>nil, "description"=>nil}} - Denise Mauldin
嗯...好吧,如果我将post更改为post:create,:disease => {:name =>''},那么测试就会成功...但我不确定为什么。 ''仍然不应该通过validates_presence_of测试,对吧? - Denise Mauldin
您在任何疾病实例上都对“保存”进行了存根处理,因此不会执行模型验证。 - zetetic
啊,我明白了。所以如果我想测试验证,那我就不应该存根save吗? - Denise Mauldin
1个回答

3
为了回答第一个问题(“我不知道如何查看Rspec返回的内容”)...您可以在spec内使用“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。我倾向于按以下样式设计控制器规范(取自每日 Ruby on Rails 测试系列 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的答案,希望我的其他回答有所帮助!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接