我在ActiveRecord中进行了以下验证。
validates :active, :inclusion => {:in => ['Y', 'N']}
我正在使用以下内容来测试我的模型验证。
should_not allow_value('A').for(:active)
should allow_value('Y').for(:active)
should allow_value('N').for(:active)
是否有更清洁,更耐用的测试方法?我目前正在使用RSpec2和shoulda matchers。
修改
经过一些环顾四周我发现,这可能是一种'好'的测试方式,如果没有为此提供任何东西,任何需要它的人都可以为它编写自己的自定义匹配器。(并且可能会将其贡献给它该项目)。可能有趣的讨论的一些链接:
答案 0 :(得分:61)
在shoulda-matchers
的最新版本中(至少从v2.7.0开始),你可以这样做:
expect(subject).to validate_inclusion_of(:active).in_array(%w[Y N])
这测试验证中可接受值的数组与此规范完全匹配。
在早期版本中,> = v1.4,shoulda_matchers
支持此语法:
it {should ensure_inclusion_of(:active).in_array(%w[Y N]) }
答案 1 :(得分:24)
如果您要测试的元素多于布尔值Y / N,那么您也可以尝试。
it "should allow valid values" do
%w(item1 item2 item3 item4).each do |v|
should allow_value(v).for(:field)
end
end
it { should_not allow_value("other").for(:role) }
您还可以使用模型中定义的常量替换%w()
,以便测试只允许常量值。
CONSTANT = %w[item1 item2 item3 item4]
validates :field, :inclusion => CONSTANT
然后测试:
it "should allow valid values" do
Model::CONSTANT.each do |v|
should allow_value(v).for(:field)
end
end
答案 2 :(得分:1)
我找到了一个自定义应该匹配(在我正在进行的项目中)试图接近测试这样的东西:
示例:
it { should validate_inclusion_check_constraint_on :status, :allowed_values => %w(Open Resolved Closed) }
it { should validate_inclusion_check_constraint_on :age, :allowed_values => 0..100 }
匹配器试图确保有一个DB约束在它试图保存它时会爆炸。我将试图给出这个想法的本质。比赛?实现做了类似的事情:
begin
@allowed_values.each do |value|
@subject.send("#{@attribute}=", value)
@subject.save(:validate => false)
end
rescue ::ActiveRecord::StatementInvalid => e
# Returns false if the exception message contains a string matching the error throw by SQL db
end
我想如果我们稍微改变上面的内容来说@subject.save
并让Rails验证爆炸,当异常字符串包含与真实异常错误消息匹配的内容时,我们可以返回false。
我知道回馈这个项目远非完美,但我想如果您真的想要测试很多:inclusion
,那么作为自定义匹配器添加到项目中可能不是一个坏主意。验证