使用RSpec和FactoryGirl测试关联验证

时间:2014-04-25 13:14:43

标签: ruby-on-rails ruby unit-testing rspec factory-bot

我目前正在尝试为验证方法编写RSpec测试。更新,保存或创建记录时会触发此方法。以下是我到目前为止的情况:

product.rb(型号)

class Product < ActiveRecord::Base

validate :single_product 

  # Detects if a product has more than one SKU when attempting to set the single product field as true
  # The sku association needs to map an attribute block in order to count the number of records successfully
  # The standard self.skus.count is performed using the record ID, which none of the SKUs currently have
  #
  # @return [boolean]
  def single_product
    if self.single && self.skus.map { |s| s.active }.count > 1
      errors.add(:single, " product cannot be set if the product has more than one SKU.")
      return false
    end
  end
end

products.rb(FactoryGirl测试数据)

FactoryGirl.define do
    factory :product do
        sequence(:name)  { |n| "#{Faker::Lorem.word}#{Faker::Lorem.characters(8)}#{n}" }
        meta_description { Faker::Lorem.characters(10) }
        short_description { Faker::Lorem.characters(15) } 
        description { Faker::Lorem.characters(20) }
        sku { Faker::Lorem.characters(5) }
        sequence(:part_number) { |n| "GA#{n}" }
        featured false
        active false
        sequence(:weighting) { |n| n }
        single false

        association :category

        factory :product_skus do 
            after(:build) do |product, evaluator|
                build_list(:sku, 3, product: product)
            end
        end
    end
end

product_spec.rb(单元测试)

require 'spec_helper'

describe Product do
    describe "Setting a product as a single product" do
        let!(:product) { build(:product_skus, single: true) }

        context "when the product has more than one SKU" do

            it "should raise an error" do
                expect(product).to have(1).errors_on(:single)
            end
        end
    end
end

正如您从 singe_product 方法中看到的那样,当单个属性设置为true且我将尝试在单个属性上触发错误时产品有多个相关的SKU。但是,在运行测试时,产品没有相关的SKU,因此无法通过上面显示的单元测试。

如何构建记录并生成可以计算的关联SKU(例如:product.skus.count)并在FactoryGirl中创建它们之前进行验证?

1 个答案:

答案 0 :(得分:0)

你可以这样写

  it 'should raise an error' do
    product = build(:product_skus, single: true)

    expect(product).not_to be_valid
  end