自定义验证方法和rspec测试

时间:2014-10-07 14:07:16

标签: ruby-on-rails ruby regex ruby-on-rails-4 rspec

我有一个自定义验证方法,它使用正则表达式匹配用户输入,然后在失败时抛出错误。

我试图理解为什么以下场景通过但第二个例子抛出

undefined method match

示例1(通行证)

# Custom Validation
def format_mobile
 regexp = "/^(07[\d]{9})$/"
  if !(mobile_no.match(regexp))
   errors[:base] << "Please check your Mobile Number"
  end
end

# rspec test
it 'is invalid with an Invalid mobile number (Company)' do
 user = FactoryGirl.build(:user, company_form: true, mobile_no: '078055031888')
 user.format_mobile
 expect(user.errors[:base]).to include("Please check your Mobile Number")
end

示例2(引发错误)

# Custom Validation
def format_mobile
 regexp = "/^(07[\d]{9})$/"
  if !(mobile_no.match(regexp))
   errors[:base] << "Please check your Mobile Number"
  end
end

# rspec test
it 'is invalid with a nil mobile number (Company)' do
 user = FactoryGirl.build(:user, company_form: true, mobile_no: nil)
 user.format_mobile
 expect(user.errors[:base]).to include("Please check your Mobile Number")
end

关于第二次失败的原因的任何指示都将非常感激,我将如何通过该测试

感谢

修改

所以如果说提供了mobile_no 07805362669,那么这将通过测试

def format_mobile
 regexp = /^(07[\d]{9})/
  if !(regexp.match(mobile_no))
   errors[:base] << "Please check your Mobile Number"
  end
end

但是mobile_no为nil的测试仍然失败

查看params如果没有mobile_no没有输入它将被传递为&#34; mobile_no&#34; =&gt;&#34;&#34;,这仍然是零但不是吗?

2 个答案:

答案 0 :(得分:2)

nil是ruby中的nil类,没有匹配方法。

String确实有匹配方法。

将{4}传递给正则表达式的regexp也是如此。所以简单地称之为

if !(regexp.match(mobile_no))
  #do_whatever
end

答案 1 :(得分:1)

这应该可以解决您的问题 我已删除""$ 现在应该通过

def format_mobile
 regexp = /^(07[\d]{9})/
  unless mobile_no.match(regexp)
   errors[:base] << "Please check your Mobile Number"
  end
end

rspec的:

let(:user) { build :user, mobile_no: '07000000000' }
it 'validates mobile number' do
  expect(user.valid?).to be_falsey
  expect(user.errors).to include 'format errror message'
end

使用regexp完全实现验证 https://gist.github.com/itsNikolay/7bc0b946770da4bf039a

但使用

验证工具要好得多
validates :mobile_no, presence: true, format: { 
  with: /^(07[\d]{9})/,
  message: 'shoud be in US format'
}