Denise Mauldin
Denise Mauldin

Reputation: 5615

Rspec Test Required parameters

I'm using FactoryGirl and Rspec for my test framework. I have a model that has a validates_presence_of validation on it. The basic Rspec framework includes a test:

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

This test doesn't work with how my application works. Rather than returning a new disease on an incorrect post, it returns an error:

Required parameter missing: disease

Question #1: I don't know how to look at what is being returned with Rspec does the post. The response object doesn't appear to be created in this case? Printing assigns(:disease) doesn't appear to contain anything. I got the error message I posted earlier by submitting a cURL post to the correct URL with empty data (which is what the rspect post should be doing), but I don't know how to get the information of what Rspec is receiving back from the post statement.

Question #2: How do I properly test the response that should be occurring - that it receives an error message saying that a required parameter is missing?

edit: So my controller seems to indicate that it should render a new disease, but the test fails. If I attempt to submit a disease missing the required parameter on the website, then it does a flash notice that says "Name can't be blank". I'm not sure how to test that in rspec.

edit #2: Included the code above. disease_params is defined at the bottom of the controller in accordance with recommendations for using the strong_parameters gem.

Thanks!

Upvotes: 3

Views: 4872

Answers (1)

aceofbassgreg
aceofbassgreg

Reputation: 3937

To answer Question 1 ("I don't know how to look at what is being returned with Rspec does the post")... You can use "puts" statements within your spec (i.e. within the it block). For instance, you can try something like this:

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

It's a valuable debugging tool. The output will be in the .s and Fs in the terminal when RSpec is running.

For Question 2, I'm not quite sure what you're looking for, but I don't know that you need to (or should) test that the invalid disease is assigned as @disease. I tend to pattern controller specs in the following style (taken from Everyday Rails Testing with RSpec which is where I learned how to write controller specs).

POST create spec example:

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 
...

You may have a reason for more thoroughly testing the controller method that I don't know about. In that case, kindly disregard my answer to Question 2 and hopefully my other answer is useful!

Upvotes: 3

Related Questions