我有以下rspec测试:
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
哪个失败并出现此错误:
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)>'
这是我的控制器的创建动作:
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
如您所见,我的操作需要来自请求的params
对象的product_id。 我应该如何将此product_id用于我的rspec测试?
我尝试过这个before
声明:
before(:each) do
ApplicationController.any_instance.stub(:product).and_return(@product = mock('product'))
end
。 。 。但它什么都没改变。我在某处遗漏了一些rspec概念。
答案 0 :(得分:0)
试试这样:
describe "POST create" do
describe "with valid params" do
it "creates a new LineItem" do
expect {
post :create, :product_id => 1
}.to change(LineItem, :count).by(1)
end
希望它有所帮助。
答案 1 :(得分:0)
我最后通过使用灯具解决了我的问题,而不是试图按照另一个答案的建议来模拟解决方案。
原因是控制器执行查询以从数据库获取信息:product = Product.find(params[:product_id])
我发现基于夹具的解决方案比使用模拟的解决方案更快解决我的问题而我无法想象如何快速存根查询(灯具也有助于控制器上的另一个测试,所以它最终帮助。
供参考:
我在测试的顶部引用了我的夹具:fixtures :products
我将测试改为:
describe "POST create" do
describe "with valid params" do
it "creates a new LineItem" do
expect {
post :create, :product_id => products(:one).id
}.to change(LineItem, :count).by(1)
end
这是我的夹具文件,products.yml:
one:
name: FirstProduct
price: 1.23
two:
name: SecondProduct
price: 4.56