1

这是我的工厂:

规格/工厂.rb

FactoryGirl.define do
  factory :user do
    username   'user1'
    time_zone  'Eastern Time (US & Canada)'
    email      'user@example.com'
    password   'testing'
  end

  factory :product do
    name 'Great Product'
    about 'this is stuff about the product'
    private false
  end
end

我的产品型号:

模型/product.rb

class Product < ActiveRecord::Base
  attr_accessible :about, :name, :private
  belongs_to :user
  has_many :prices
  validates_presence_of :name
  validates_presence_of :user_id
end

这是我使用 Rspec 和Shoulda寻求帮助的测试:

规格/模型/product_spec.rb

require 'spec_helper'

describe Product do
  before(:each) do
    FactoryGirl.build(:product)
  end

  it { should have_many(:prices) }
  it { should belong_to(:user) }

  it { should validate_presence_of :name }
  it { should validate_presence_of :user_id }
end

测试通过了,但我认为我应该为协会这样做:

factory :product do
    name 'Great Product'
    about 'this is stuff about the product'
    private false

    user # <--
end

如果我对错误执行此操作,所有测试都将失败:

ActiveRecord::RecordInvalid:
       Validation failed: Time zone is not included in the list

那么它真的分配了我在工厂创建的用户吗?

编辑

用户.rb

  has_many :products

  validates_presence_of :username
  validates_presence_of :time_zone
  validates_format_of :username, :with => /^(?=(.*[a-zA-Z]){3})[a-zA-Z0-9]+$/
  validates_uniqueness_of :email         
  validates_uniqueness_of :username, :case_sensitive => false
  validates_length_of :username, :within => 3..26
  validates_inclusion_of :time_zone, :in => ActiveSupport::TimeZone.us_zones
4

2 回答 2

1

您的验证失败导致您在工厂中使用的时区错误

1.9.3p194 :009 > ActiveSupport::TimeZone.us_zones
=> [(GMT-10:00) Hawaii, (GMT-09:00) Alaska, (GMT-08:00) Pacific Time (US & Canada), (GMT-07:00) Arizona, (GMT-07:00) Mountain Time (US & Canada), (GMT-06:00) Central Time (US & Canada), (GMT-05:00) Eastern Time (US & Canada), (GMT-05:00) Indiana (East)]

1.9.3p194 :010 > ActiveSupport::TimeZone.us_zones.include?('Eastern Time (US & Canada)')
=> false 

你应该在你的工厂使用类似的东西

ActiveSupport::TimeZone.create("Eastern Time (US & Canada)")

如果您希望您的验证通过。

或者,如果您想将时区存储在数据库中的字符串值中,您应该将代码更改为类似这样的内容

# user.rb
...
validates_inclusion_of :time_zone, :in => ActiveSupport::TimeZone.us_zones.map(&:to_s)

# spec/factories.rb
...
time_zone  "(GMT-05:00) Eastern Time (US & Canada)"
...
于 2012-09-10T18:43:34.783 回答
1

当你这样做

  it { should validate_presence_of :user_id }

shoulda 验证何时user_id缺少您的模型无效,并且错误列表包含 user_id 的错误以及相应的消息。对象最初是否有效(或其他属性有错误)无关紧要:这就是为什么当您的工厂没有为产品分配用户时您的测试通过

我怀疑您的其他测试失败,因为您正在测试time_zone时区对象数组中是否包含字符串 () -'Eastern Time (US & Canada)'不等于相应的时区对象(很像"1" != 1

于 2012-09-10T18:50:33.343 回答