ruby-on-rails - 如何使用 Rspec 验证 rails 中属性的长度和数字

标签 ruby-on-rails ruby rspec shoulda

我有一个包含名字、姓氏和电话号码的客户模型。我想让用户以任何格式输入电话号码,例如 555-555-5555 或 (555)555-5555 或 555.555.5555

这是我的客户模型

class Customer < ActiveRecord::Base
  before_validation(on: :create) { format_phone_number }

  validates_presence_of :first_name, :last_name, :phone_number

  validates :phone_number, numericality: true, length: {minimum: 10}

  private

  def format_phone_number
    self.phone_number = phone_number.gsub(/[^0-9]/, "") if attribute_present?("phone_number")
  end
end

format_phone_number 方法在验证前去掉所有非数字字符,然后我想验证它的长度是 10

这是我的规范

describe Customer do
  it { should validate_presence_of(:first_name)}
  it { should validate_presence_of(:last_name)}
  it { should validate_presence_of(:phone_number)}
  it { should ensure_length_of(:phone_number).is_at_least(10) }

  describe "phone_number" do
    it "should remove non-numeric characters" do
      bob = Fabricate(:customer, first_name: "Bob", last_name: "Smith", phone_number: "555-777-8888" )
      expect(bob.phone_number).to eq('5557778888')
    end
  end
end 

当我运行这个时,我得到了这个错误

Failure/Error: it { should ensure_length_of(:phone_number).is_at_least(10) }
       Did not expect errors to include "is too short (minimum is 10 characters)" when phone_number is set to "xxxxxxxxxx", got error: is too short (minimum is 10 characters)

所以看起来 Rspec 正在尝试用 "xxxxxxxxxx"测试长度,而我的方法是在对象被保存之前去除所有的 x。什么是更好的测试或实现方法?

最佳答案

这可能是因为 format_phone_number 回调仅在验证之前触发。虽然我没有使用 Fabrication gem,the documentation表示它初始化 ActiveRecord 对象但不调用 savevalid?。因此 before_validation 回调不会被触发。尝试在 rspec 断言之前添加 valid?:

it "should remove non-numeric characters" do
  bob = Fabricate(:customer, first_name: "Bob", last_name: "Smith", phone_number: "555-777-8888" )
  bob.valid?
  expect(bob.phone_number).to eq('5557778888')
end

或者您可以使用 after_initialize ActiveRecord callback在构建 Customer 对象后立即触发格式化:

class Customer < ActiveRecord::Base
  #...
  after_initialize :format_phone_number

  #...
end

关于ruby-on-rails - 如何使用 Rspec 验证 rails 中属性的长度和数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26790628/

相关文章:

css - 突出显示标题和发布标题

ruby-on-rails - 我们可以在 Ruby on Rails ActiveRecord 的一个查询中插入多行吗?

ruby - 计数、尺寸、长度……Ruby 中的选择太多了吗?

Ruby 通过索引访问多个数组元素(子数组)

testing - 我将如何以 BDD 风格在 Rhomobile 中测试 Controller ?

ruby-on-rails - 在测试中关闭来自 Devise 的电子邮件发送 (Rspec)

ruby-on-rails - Rspec+Capybara - 它不会改变任何记录?

ruby-on-rails - 为什么 `duplicable?` 是这样定义的?

ruby-on-rails - 如何使用带有 Rails 4 的 rspec 检查记录是否保存在数据库中?

python - 适用于 Ruby、Ruby on Rails、Python 的智能感知