除非另一个字段为真 rails,否则如何测试验证存在?
how to test validate presence unless another field is true rails?
鉴于此代码:
field :start_now, type: Boolean, :default => true
field :time_zone
validates :time_zone, inclusion: {
in: ActiveSupport::TimeZone.zones_map.keys
}, unless: :start_now?
我创建了这个 rspec 测试,但它很长而且不干。像这样的唯一原因是 "unless" 条件:
describe "#time_zone" do
context "scheduled" do
before :each do
subject.start_now = false
end
it { is_expected.to validate_inclusion_of(:time_zone).in_array(ActiveSupport::TimeZone.zones_map.keys) }
end
context "run now" do
before :each do
subject.start_now = true
end
it { is_expected.not_to validate_inclusion_of(:time_zone).in_array(ActiveSupport::TimeZone.zones_map.keys) }
end
end
有更短的方法吗?
真的没有必要让它比这更短。这两个测试都准确地描述了他们正在测试的内容,而且它们非常具体 关于那些测试。
根据我在测试中看到的情况,您希望您的测试是 DAMP。这并不意味着它们不干燥,但它确实意味着你不应该向后弯曲以使其尽可能小和窄。
您的代码有两个不同且互斥的状态,这取决于布尔值 start_now?
。你必须测试这两种状态,而且真的没有办法解决这个问题。也没有重复;您正在测试两个不同的分支。
虽然您的上下文 could use a wee bit of a verbiage clean up,但它们非常善于描述您需要做什么。
这里和改进。下一个代码更干燥,同时像以前一样更潮湿:
describe "#time_zone" do
let(:validate_time_zone) { validate_inclusion_of(:time_zone).in_array(ActiveSupport::TimeZone.zones_map.keys }
context "scheduled" do
before :each do
subject.start_now = false
end
it { is_expected.to validate_time_zone }
end
context "run now" do
before :each do
subject.start_now = true
end
it { is_expected.not_to validate_time_zone}
end
end
好的,所以我明白 DAMP(对我来说是一个新词)很好。我今天感觉好多了,因为我一直在思考测试太干而使它们很难阅读的问题。
有时我喜欢使用在外部 before :each
中调用的每个上下文中的 let
来编写规范。这避免了为每个上下文重复 before :each
。
describe "#time_zone" do
let(:validate_time_zone) do
validate_inclusion_of(:time_zone).in_array(ActiveSupport::TimeZone.zones_map.keys
end
before :each do
subject.start_now = start_now
end
context "scheduled" do
let(:start_now) { false }
it { is_expected.to validate_time_zone }
end
context "run now" do
let(:start_now) { true }
it { is_expected.not_to validate_time_zone}
end
end
鉴于此代码:
field :start_now, type: Boolean, :default => true
field :time_zone
validates :time_zone, inclusion: {
in: ActiveSupport::TimeZone.zones_map.keys
}, unless: :start_now?
我创建了这个 rspec 测试,但它很长而且不干。像这样的唯一原因是 "unless" 条件:
describe "#time_zone" do
context "scheduled" do
before :each do
subject.start_now = false
end
it { is_expected.to validate_inclusion_of(:time_zone).in_array(ActiveSupport::TimeZone.zones_map.keys) }
end
context "run now" do
before :each do
subject.start_now = true
end
it { is_expected.not_to validate_inclusion_of(:time_zone).in_array(ActiveSupport::TimeZone.zones_map.keys) }
end
end
有更短的方法吗?
真的没有必要让它比这更短。这两个测试都准确地描述了他们正在测试的内容,而且它们非常具体 关于那些测试。
根据我在测试中看到的情况,您希望您的测试是 DAMP。这并不意味着它们不干燥,但它确实意味着你不应该向后弯曲以使其尽可能小和窄。
您的代码有两个不同且互斥的状态,这取决于布尔值 start_now?
。你必须测试这两种状态,而且真的没有办法解决这个问题。也没有重复;您正在测试两个不同的分支。
虽然您的上下文 could use a wee bit of a verbiage clean up,但它们非常善于描述您需要做什么。
这里和改进。下一个代码更干燥,同时像以前一样更潮湿:
describe "#time_zone" do
let(:validate_time_zone) { validate_inclusion_of(:time_zone).in_array(ActiveSupport::TimeZone.zones_map.keys }
context "scheduled" do
before :each do
subject.start_now = false
end
it { is_expected.to validate_time_zone }
end
context "run now" do
before :each do
subject.start_now = true
end
it { is_expected.not_to validate_time_zone}
end
end
好的,所以我明白 DAMP(对我来说是一个新词)很好。我今天感觉好多了,因为我一直在思考测试太干而使它们很难阅读的问题。
有时我喜欢使用在外部 before :each
中调用的每个上下文中的 let
来编写规范。这避免了为每个上下文重复 before :each
。
describe "#time_zone" do
let(:validate_time_zone) do
validate_inclusion_of(:time_zone).in_array(ActiveSupport::TimeZone.zones_map.keys
end
before :each do
subject.start_now = start_now
end
context "scheduled" do
let(:start_now) { false }
it { is_expected.to validate_time_zone }
end
context "run now" do
let(:start_now) { true }
it { is_expected.not_to validate_time_zone}
end
end