Reputation: 21015
I have the following code:
RSpec.describe OtsState do
let(:campaign) { build(:campaign, from: Time.now+1.weeks, to: Time.now+2.weeks) }
subject { campaign.deployment.ots_state }
before { campaign.deployment.build_ots_state }
describe "#set_target" do
def check_ots_target(target,expected)
ots_state = subject
ots_state.set_target(target)
expect(ots_state.ots_target).to eq(expected)
end
it 'should set target to 5 when 1 week period and set target to 5' do
check_ots_target(5,5)
end
it 'should set target to 2 when 2 week period and set target to 1' do
campaign.set(to: campaign.from+2.weeks)
check_ots_target(1,2)
end
it 'should set target to 1 when 1 day period and set target to 7' do
campaign.set(to: campaign.from+1.days)
check_ots_target(7,1)
end
end
end
is there a way in RSpec to write it as a single test with 3 parameter sets?
Upvotes: 0
Views: 27
Reputation: 47548
You could use RSpec matchers with a fluent interface:
RSpec::Matchers.define :have_ots_target do |expected|
match do |ots_state|
ots_state.ots_target == expected
end
description do
"have ots_target #{expected} when period is #{@period.inspect} and target is #{@target}"
end
chain :when_period_is do |period|
@period = period
end
chain :and_target_is do |target|
@target = target
end
end
which allows something like this:
describe do
let(:period) { 1.weeks }
let(:target) { 5 }
it { is_expected.to have_ots_target(5).when_period_is(period).and_target_is(target) }
end
but I prefer to just repeat the example and change the inputs:
describe "#set_target" do
describe "when period is 2 weeks" do
let(:period) { 2.weeks }
describe "and target is 1" do
it "returns 2" do
expect(subject.set_target(1).to eq 2
end
end
end
end
which is easier to write and easier to read.
Upvotes: 1