Reputation: 5615
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
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