Alb*_*lbz 7 ruby tdd bdd rspec
我有一个名为"FizzBuzz"的游戏的非常简单的Ruby实现(即,如果数字是3的倍数则返回"Fizz",如果是5的倍数则返回"Buzz",如果是多个,则返回"FizzBuzz"和原始数字,如果它不符合以前的任何条件):
class FizzBuzz
def answer(number)
multiple3 = number%3 == 0
multiple5 = number%5 == 0
return case
when (multiple3 and multiple5) then "FizzBuzz"
when multiple3 then "Fizz"
when multiple5 then "Buzz"
else number
end
end
end
Run Code Online (Sandbox Code Playgroud)
我使用RSpec编写了一个测试来验证每个条件:
require "rspec"
require "./fizzBuzz"
RSpec.describe "#answer" do
it "returns Buzz when number is multiple of 3" do
result = FizzBuzz.new.answer(3)
expect(result).to eq("Fizz")
end
it "returns Buzz when number is multiple of 5" do
result = FizzBuzz.new.answer(5)
expect(result).to eq("Buzz")
end
it "returns a number when the input number is neither multiple of 3 nor 5" do
result = FizzBuzz.new.answer(11)
expect(result).to eq(11)
end
end
Run Code Online (Sandbox Code Playgroud)
测试完美无缺,然而,我正在使用具体值(即3,5和11).
我的问题是:如果我想使用各种值(例如从1到10000)测试我的FizzBuzz Ruby脚本怎么办?
我知道我可以通过直接在RSpec中使用每个循环和案例来解决这个问题,但是,我担心的是,如果在我的测试中我采用与要测试的Ruby脚本相同的条件语句(即when number%3 == 0 then "Fizz"等等),我将最终使用RSpec脚本测试我的代码,该脚本遵循与要测试的脚本完全相同的逻辑,因此测试可能会成功通过.
会有什么选择?是否有使用大量值(例如使用循环)而不是硬编码或特定值来编写测试的最佳实践?
Yul*_*ule 19
这里可能的中途点是在RSpec测试中循环可能的答案.保持代码干燥很重要,但保持测试干燥也是如此,这有时会被低估.
这样的事情怎么样:
RSpec.describe "#answer" do
expected_values = {'3': 'Fizz', '5': 'Buzz', '6': 'Fizz', '11': '11', '15': 'FizzBuzz'}
expected_values.each do |val, expected|
it "returns #{expected} when number is #{val}" do
result = FizzBuzz.new.answer(val.to_i)
expect(result).to eq(expected)
end
end
end
Run Code Online (Sandbox Code Playgroud)
这样,您可以通过将测试添加到expected_values哈希中来轻松添加测试,但如果方法名称发生更改或类似,您只需在一个地方更改它
小智 8
为了支持已接受的答案,我建议将更广泛的测试包装在上下文块中,以便测试与其他代码保持隔离:
RSpec.describe "#answer" do
context 'when testing inputs and answers' do
RESULTS = { 3 => "Fizz",
5 => "Buzz",
11 => 11 }
RESULTS.each do |value, answer|
it "returns #{answer} when the input is #{value}" do
result = FizzBuzz.new.answer(value)
expect(result).to eq(answer)
end
end
end
end
Run Code Online (Sandbox Code Playgroud)