-
-
Save shilovk/e05fa5150ea687789f07a4c39c736c38 to your computer and use it in GitHub Desktop.
RSpec easy loop testing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
class Decider | |
def self.undecided | |
loop do | |
break if decision? | |
end | |
end | |
def self.decision? | |
# code yielding true or false | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
require 'rails_helper' | |
RSpec.describe Decider, type: :model do | |
describe '.undecided' do | |
subject { Decider.undecided } | |
after { subject } | |
context 'loop testing method 1' do | |
# Break the loop by passing a breaking result/value in the spec setup. | |
context 'a decision has been made' do | |
before do | |
allow(Decider).to receive(:decision?) { true } | |
end | |
it 'breaks the loop' do | |
expect(Decider).to receive(:decision?).once | |
end | |
end | |
context 'no decision has been made' do | |
# `.and_return()` takes multiple arguments for iterative results | |
# The last arg of true breaks the loop in the application code | |
before do | |
allow(Decider).to receive(:decision?).and_return(false, false, true) | |
end | |
it 'continues to loop' do | |
expect(Decider).to receive(:decision?).exactly(3).times | |
end | |
end | |
end | |
context 'loop testing method 2' do | |
# Take control of the loop with `.and_yield`, which can be | |
# chained together for additional passes through the loop | |
before do | |
allow(Decider).to receive(:loop).and_yield.and_yield | |
end | |
context 'a decision has been made' do | |
before do | |
allow(Decider).to receive(:decision?) { true } | |
end | |
it 'breaks the loop' do | |
expect(Decider).to receive(:decision?).once | |
end | |
end | |
context 'no decision has been made' do | |
before do | |
allow(Decider).to receive(:decision?).and_return(false, false) | |
end | |
it 'continues to loop' do | |
expect(Decider).to receive(:decision?).exactly(:twice) | |
end | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment