0

私は次のものを持っています:

def destroy
    @product = Product.find(params[:id])
    @product.destroy

    respond_to do |format|
      format.html { redirect_to products_url }
      format.json { head :no_content }
    end
  end

と私のテスト:

test "should destroy product" do
    assert_difference('Product.count', -1) do
      delete :destroy, :id => @product
    end

    assert_redirected_to products_path
  end

そして私は得る:

# Running tests:

...............F......

Finished tests in 0.628844s, 34.9848 tests/s, 55.6577 assertions/s.

  1) Failure:
test_should_destroy_product(ProductsControllerTest) [/Users/noahc/Dropbox/Projects/depot/test/functional/products_controller_test.rb:51]:
"Product.count" didn't change by -1.
<2> expected but was
<3>.

22 tests, 35 assertions, 1 failures, 0 errors, 0 skips
Errors running test:functionals! #<RuntimeError: Command failed with status (1): [/usr/local/bin/ruby -I"lib:test" -I"/usr/l...]>

これが失敗する理由はありますか?

アップデート

コメントアウトした場合:

before_destroy :ensure_not_referenced_by_any_line_item

#ensure that there are no line items referencing this product
    def ensure_not_referenced_by_any_line_item
      if line_items.any?
        return true
      else errors.add(:base, 'Line Items present')
        return false
      end
    end

テストに合格します。ただし、@productには広告申込情報はありません。それは単なる備品です。

4

2 に答える 2

0

私はあなたが追加する必要があると思いto_paramます@product

test "should destroy product" do
assert_difference('Product.count', -1) do
  delete :destroy, :id => @product.to_param
end

assert_redirected_to products_path
end
于 2012-07-19T15:16:29.990 に答える
0

おそらく、コールバックをコメントアウトして、誰かの注文履歴に残っている場合に製品が削除されるのを防ぎたくないので、これを検討します(将来の購入または現在の購入については、評価されるアクティブ/非アクティブステータス列を実装します最終的なチェックアウトの前; 製品の表示は引き続き可能ですが、たとえば製品が在庫切れの場合はチェックアウトできません)。これらのテストでは、product.rb の before_destroy が考慮されます。ここでは、製品が購入されなかった場合にどのようになるかをオンザフライでシミュレートしています。または、フィクスチャを更新してみてください。

test "product has line items" do
  assert_not_equal 0, @product.line_items.count
end

test "product has no line items" do
  @product.line_items.each do |item|
    item.destroy
  end

  assert_equal 0, @product.line_items.count
end

test "should destroy product" do
    assert_difference('Product.count', -1) do

    # "simulate" a product that has never been added to cart
    # alternatively you could update your fixtures to do this

    @product.line_items.each do |item|
      item.destroy
    end

    delete :destroy, id: @product
  end

  assert_redirected_to products_path
end

最後に、コントローラーとビューを更新して、このフラッシュ通知を追加して、何が起こっているかを確認できるようにしてください。

# DELETE /products/1
# DELETE /products/1.json
def destroy
  @product = Product.find(params[:id])
  if @product.destroy
    flash[:notice] = "#{@product.title} successfully deleted"
  else
    flash[:notice] = "It appears there are other carts that currently have #{@product.title} so we won't delete it at this time"
  end

  respond_to do |format|
    format.html { redirect_to products_url }
    format.json { head :no_content }
  end
end

破棄リンクが表示される製品のビューで、これを使用する場合は、上部に通知が印刷されていることを確認してください。

<p id="notice"><%= notice %></p>
于 2013-03-23T07:25:54.680 に答える