I have the following rspec test:
def valid_attributes
{ "product_id" => "1" }
end
describe "POST create" do
describe "with valid params" do
it "creates a new LineItem" do
expect {
post :create, {:line_item => valid_attributes}, valid_session #my valid_session is blank
}.to change(LineItem, :count).by(1)
end
Which fails with this error:
1) LineItemsController POST create with valid params redirects to the created line_item
Failure/Error: post :create, {:line_item => valid_attributes}, valid_session
ActiveRecord::RecordNotFound:
Couldn't find Product without an ID
# ./app/controllers/line_items_controller.rb:44:in `create'
# ./spec/controllers/line_items_controller_spec.rb:87:in `block (4 levels) in <top (required)>'
This is my controller’s create action:
def create
@cart = current_cart
product = Product.find(params[:product_id])
@line_item = @cart.line_items.build(:product => product)
respond_to do |format|
if @line_item.save
format.html { redirect_to @line_item.cart, notice: 'Line item was successfully created.' }
format.json { render json: @line_item.cart, status: :created, location: @line_item }
else
format.html { render action: "new" }
format.json { render json: @line_item.errors, status: :unprocessable_entity }
end
end
end
As you can see, my action expects a product_id from the request’s params object. How should I work this product_id into my rspec test?
I’ve tried placing this before statement:
before(:each) do
ApplicationController.any_instance.stub(:product).and_return(@product = mock('product'))
end
. . . but it changes nothing. I am missing some rspec concept here somewhere.
I ended up resolving my issue by using a fixture instead of attempting to mock the solution as suggested in another answer.
The reason for this is that the controller does the query to get information from the database:
product = Product.find(params[:product_id])and I found a fixture-based solution was quicker to resolve my problem than one using a mock and I could not figure out how to stub the query quickly (the fixtures also help with another test on the controller so it eventually helped anyway.For reference:
I referenced my fixture with this line toward the top of the test:
fixtures :productsI changed my test to:
And here is my fixture file, products.yml: