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

这是工厂通常比铁路社区中的固定装置更受青睐的原因之一。Fixtures 不会自动加载它们的关联,因此往往很脆弱。您的夹具的 product_id 为 1,但该产品不存在。

我不确定如何解决您的特定问题,但我建议您:

  1. 在您的测试中创建一个 id=1 的产品。
  2. 创建一个 id=1 的 Product 固定装置并将其加载到您的设置中
  3. 切换到工厂(最好是这个)

编辑

如此处所述,您还可以使用标签引用进行关联。因此,如果您有一个名为“tv”的产品夹具,您可以删除 line_item 夹具的 product_id 字段并将其替换为product: tv

于 2012-05-25T21:10:32.727 回答