0

line_item モデルの破棄単体テストが、「id=1 の製品が見つかりませんでした」というエラーで失敗しています。データベースから取得するときに例外がスローされるため、Rails は私の line_item を破棄できないようです。ここに私の LineItem モデルがあります:

class LineItem < ActiveRecord::Base
  belongs_to :product
  belongs_to :cart
  
  def total_price
    product.price * quantity
  end
end

そして、ここにテストスイートがあります:

require 'test_helper'

class LineItemsControllerTest < ActionController::TestCase
  setup do
    @line_item = line_items(:one)
    Rails.logger.debug(@line_item.to_yaml)
    Rails.logger.debug(Product.all.to_yaml)
  end

  test "should get index" do
    get :index
    assert_response :success
    assert_not_nil assigns(:line_items)
  end

  test "should get new" do
    get :new
    assert_response :success
  end

  test "should create line_item" do
    assert_difference('LineItem.count') do
      post :create, product_id: products(:ruby).id
    end

    assert_redirected_to cart_path(assigns(:line_item).cart)
  end

  test "should show line_item" do
    get :show, id: @line_item
    assert_response :success
  end

  test "should get edit" do
    get :edit, id: @line_item
    assert_response :success
  end

  test "should update line_item" do
    put :update, id: @line_item, line_item: @line_item.attributes
    assert_redirected_to line_item_path(assigns(:line_item))
  end

  test "should destroy line_item" do
    Rails.logger.debug "Breaking!"
    assert_difference('LineItem.count', -1) do
      delete :destroy, id: @line_item
    end

    assert_redirected_to cart_path(path)
  end
end

そして、ここに私が記録した部分があります:

    Breaking!
  [1m[35m (0.1ms)[0m  SELECT COUNT(*) FROM "line_items" 
Processing by LineItemsController#destroy as HTML
  Parameters: {"id"=>"980190962"}
  [1m[36mLineItem Load (0.1ms)[0m  [1mSELECT "line_items".* FROM "line_items" WHERE "line_items"."id" = ? LIMIT 1[0m  [["id", "980190962"]]
  [1m[35mProduct Load (0.1ms)[0m  SELECT "products".* FROM "products" WHERE "products"."id" = ? LIMIT 1  [["id", 1]]
Completed 500 Internal Server Error in 3ms
  [1m[36m (0.1ms)[0m  [1mrollback transaction[0m
  [1m[35m (0.1ms)[0m  begin transaction
  [1m[36mLineItem Load (0.1ms)[0m  [1mSELECT "line_items".* FROM "line_items" WHERE "line_items"."id" = ? LIMIT 1[0m  [["id", 980190962]]
--- !ruby/object:LineItem
attributes:
  id: 980190962
  product_id: 1
  cart_id: 1
  created_at: 2012-05-25 20:37:17.000000000 Z
  updated_at: 2012-05-25 20:37:17.000000000 Z
  quantity: 1
  product_price: 

  [1m[35mProduct Load (0.2ms)[0m  SELECT "products".* FROM "products" 
---
- !ruby/object:Product
  attributes:
    id: 207281424
    title: Programming Ruby 1.9
    description: Ruby is the fastest growing and most exciting dynamic language out
      there.  If you need to get working programs delivered fast, you should add Ruby
      to your toolbox.
    image_url: ruby.png
    price: 49.5
    created_at: 2012-05-25 20:37:17.000000000 Z
    updated_at: 2012-05-25 20:37:17.000000000 Z  

編集:ここに製品モデルがあります:

class Product < ActiveRecord::Base
  has_many :line_items
  
  before_destroy :ensure_not_referenced_by_any_line_item
  
  # Validation
  validates :title, :description, :image_url, presence: true
  validates :title, length: {
    minimum: 10,
    message: "must be at least %{count} characters long"
  }
  validates :price, numericality: { greater_than_or_equal_to: 0.01 }
  validates :title, uniqueness: true
  validates :image_url, allow_blank: true, format: {
    with: %r{\.(gif|jpg|png)$}i,
    message: 'must be a URL for GIF, JPG or PNG image.'
  }
  
  private
  
  def ensure_not_referenced_by_any_line_item
    if line_items.empty?
      return true
    else
      errors.add :base, 'Line items present'
      return false
    end
  end
end
4

1 に答える 1

1

これが、Rails コミュニティで一般的に固定具よりもファクトリが好まれる理由の 1 つです。フィクスチャは関連付けを自動的にロードしないため、壊れやすい傾向があります。フィクスチャの product_id は 1 ですが、その製品は存在しません。

特定の問題を正確に修正する方法はわかりませんが、次のいずれかをお勧めします。

  1. テストで id=1 の製品を作成します。
  2. id=1 の Product フィクスチャを作成し、セットアップにロードします
  3. 工場に切り替える(できればこれ)

編集

hereで説明されているように、関連付けにラベル参照を使用することもできます。したがって、「tv」という製品フィクスチャがある場合、line_item フィクスチャの product_id フィールドを削除して、product: tv

于 2012-05-25T21:10:32.727 に答える