[英]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.