Für Methoden, die True oder False zurückgeben, gibt es in Ruby die Konvention, den Methodennamen mit einem ? abzuschliessen. RSpec bietet für diese Konvention eine verkürzte Testnotation an, sogenannte predicate matchers. Damit kann die Testerwartung sehr viel prägnanter ausgedrückt werden.
Lange RSpec Tests
Zunächst eine beispielhafte Ausgangssituation: eine Stadt ist eine Metropole, wenn sie mehr als eine Million Einwohner hat. Die Implementierung soll in der Methode City#metropolis? stattfinden.
Die Erwartungshaltung in RSpec:
describe City do
subject { City.new }
describe '#metropolis?' do
context 'without population' do
it 'is false' do
expect(subject.metropolis?).to be false
end
end
context 'when population is less than a million' do
before { city.population = 999_999 }
it 'is false' do
expect(subject.metropolis?).to be false
end
end
context 'when population is equal to a million' do
before { city.population = 1_000_000 }
it 'is true' do
expect(subject.metropolis?).to be true
end
end
end
end
Allerdings können die selben Erwartungen auch sehr viel kürzer und prägnanter ausgedrückt werden.
Kurze RSpec Tests
Die selben Tests:
describe City do
subject { City.new }
describe '#metropolis?' do
context 'without population' do
it { is_expected.to_not be_metropolis }
end
context 'when population is less than a million' do
before { subject.population = 999_999 }
it { is_expected.to_not be_metropolis }
end
context 'when population is equal to a million' do
before { city.population = 1_000_000 }
it { is_expected.to be_metropolis }
end
end
end
Genau wie die RSpec eigenen Matcher be_empty oder be_nil erwartet RSpec bei den predicate matchers, dass das Testobjekt eine Methode hat, die sich aus dem Matcher ableiten läßt: be_xxx => xxx? und ruft diesen auf.
Implementierung
Die Implementierung des Beispiels:
class City
METROPOLIS_POPULATION = 1_000_000
attr_accessor :population
def metropolis?
population.to_i >= METROPOLIS_POPULATION
end
end
und die Testergebnisse:
City
#metropolis?
without population
should not be metropolis
when population less than a million
should not be metropolis
when population equal to a million
should be metropolis
Finished in 0.00358 seconds (files took 0.48847 seconds to load)
3 examples, 0 failures