[英]How do I write an Rspec test for a Ruby method that contains variable that contains 'gets.chomp'?
我查看了其他测试示例,但大多数其他示例不一定有一个等于“gets.chomp.downcase”的变量,这让我很难测试。
rest 用于国际象棋游戏,但我正在努力做到这一点,因此如果您在介绍中输入“新”,它将调用方法#instructions,该方法会显示说明并询问您是否准备好下棋。
这是方法#introduction
def introduction
puts " \n"
print " Welcome to chess! "
puts "What would you like to do?"
puts "
* Start a new Game -> Enter 'new'
* Load a saved Game -> Enter 'load'
* Exit -> Enter 'exit'"
input = gets.chomp.downcase
if input == "new"
instructions
elsif input == "load"
load_game
elsif input == "exit"
exit!
else
introduction
end
end
这是我对其进行的测试,它不断显示错误“失败/错误:输入=gets.chomp.downcase”
“NoMethodError:nil:NilClass 的未定义方法‘chomp’”
describe Game do
describe "#introduction" do
it "starts a new game with input 'new'" do
io = StringIO.new
io.puts "new"
$stdin = io
game = Game.new
game.introduction
allow(game).to receive(:gets).and_return(io.gets)
expect(game).to receive(:instructions)
end
end
end
您的方法存在多个问题。 我不会一一列举,而是关注三个关键错误:
您的代码和测试肯定还有其他问题,但是一旦您从测试用例中消除对#gets 的依赖,我就会从这里开始。 例如,要测试方法中的各种路径,您可能应该为每个预期值配置一系列测试,其中 #and_return 显式返回new
、 load
或其他。
更务实的是,您很可能会因为您先编写代码而苦苦挣扎,而现在正在尝试进行 retrofit 测试。 虽然您可能会修补一些东西以使其事后可测试,但您最好重构代码以允许在测试中直接注入。 例如:
def show_prompt
print prompt =<<~"EOF"
Welcome to chess! What would you like to do?
* Start a new Game -> Enter "new"
* Load a saved Game -> Enter "load"
* Exit -> Enter "exit"
Selection:\s
EOF
end
def introduction input=nil
show_prompt
# Use an injected input value, if present.
input ||= gets.chomp.downcase
case input
when "new" then instructions
when "load" then load_game
when "exit" then exit!
else introduction
end
end
这首先避免了存根或模拟 object 的需要。 您的测试现在可以简单地调用带有或不带有显式值的#introduction。 这使您可以花时间测试逻辑分支和方法输出,而不是编写大量脚手架来支持 IO#gets 调用的 mocking 或避免与 nil 相关的异常。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.