Rspec中测试验证的简短方法

时间:2016-03-28 14:21:21

标签: ruby-on-rails rspec

我想要一种简单的方法来测试我的验证。我的测试重点是集成,而不是验证,我不使用TDD。话虽如此,我想替换:

# Estate model specs

describe "#name" do
  it "is required" do
    estate.name = nil
    estate.valid?
    expect(estate.errors).to have_key(:name)
  end
end

describe "#company" do
  it "is required" do
    estate.company = nil
    estate.valid?
    expect(estate.errors).to have_key(:company)
  end
end

# and so on..

对某些人来说:

# Estate model specs

requiredFields = [:name, :company, :price, :region, :regions, :typologies, :image]
requiredFields.each do |requiredField|
  describe "##{requiredField}" do
    it "is required" do
      estate[requiredField] = nil
      estate.valid?
      expect(estate.errors).to have_key(requiredField)
    end
  end
end

字段名称和价格有效,问题在于关联:

Estate
  is an instance of Estate
  validations
    with required fields
      should be valid
    #name
      is required
    #company
      is required (FAILED - 1)
    #price
      is required
    #region
      is required (FAILED - 2)
    ...

我认为问题是estate[requiredField]。如果我改为company_id就行了。如何在foreach中执行类似estate.requiredField的操作?

2 个答案:

答案 0 :(得分:2)

您可以使用Ruby的send方法执行estate.requiredField,该方法将其参数作为接收方的方法调用:

estate.send(requiredField)

由于您正在分配,因此您需要在字段名称中插入=foo=方法接受一个参数,在方法名称后面作为send的连续参数传递:

estate.send("#{requiredField}=", nil)`

需要注意的是,由于send最终会在接收方内调用所请求的方法,因此最终可能会绕过protectedprivate方法。

class Dog
   private
   def bark
     puts 'Woof'
   end
 end

Dog.new.bark
# NoMethodError: private method 'bark' called for #<Dog:0x007fd28bad7590>

Dog.new.send :bark
# Woof

答案 1 :(得分:1)

尝试使用object.send

estate.send("#{requiredField}=", value) # setter, estate.requiredField=value
estate.send(requiredField) # getter, estate.requiredField

或者使用https://github.com/thoughtbot/shoulda-matchers进行此类测试