鉴于此代码:
field :start_now, type: Boolean, :default => true
field :time_zone
validates :time_zone, inclusion: {
in: ActiveSupport::TimeZone.zones_map.keys
}, unless: :start_now?
我已经创建了这个rspec测试,但它很长而不是DRY。而这样的唯一原因是因为"除非"条件:
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
有没有更短的方法呢?
答案 0 :(得分:1)
确实没有必要让它更短。这两项测试都准确描述了他们正在测试的内容,并且他们非常具体关于这些测试。
从我在测试中看到的情况来看,您希望测试成为DAMP。这并不意味着他们不会干,但 意味着你不应该向后弯曲以使其尽可能小而窄。
您的代码有两个不同且互斥的状态,这取决于布尔值start_now?
。你必须测试这两种状态,而且真的没有办法解决这个问题。也没有重复;你正在测试两个不同的分支。
在您的上下文could use a wee bit of a verbiage clean up中,他们非常擅长描述您需要做的事情。
答案 1 :(得分:1)
这里和改进。下一个代码更干,同时比以前更多DAMP:
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(对我来说是一个新词)是好的。我今天感觉好多了,因为我一直在考虑过度干燥测试并使它们难以阅读的问题。
答案 2 :(得分:1)
有时我喜欢使用外部let
中调用的每个上下文中的before :each
编写我的规范。这样可以避免为每个上下文重复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