2017-08-10 71 views
1

我正在嘗試編寫一個spec來測試顯示一個井字棋板。我正在使用方法capture,但在運行規範時會引發錯誤。我正在使用捕獲來獲取方法調用的輸出。 https://apidock.com/rails/Kernel/capture 這裏是我的方法:RSpec的未定義方法`capture'

def display_board 
    puts " #{grid[0]} | #{grid[1]} | #{grid[2]} " 
    puts "-----------" 
    puts " #{grid[3]} | #{grid[4]} | #{grid[5]} " 
    puts "-----------" 
    puts " #{grid[6]} | #{grid[7]} | #{grid[8]} " 
    end 

這裏是我的Rspec的測試:

context "#display_board" do 
    output = capture(:stdout) { board.display_board} 
    rows = output.split("\n") 
    binding.pry 
    expect(rows[0]).to eq(" | | ") 
    expect(rows[1]).to eq("-----------") 
    expect(rows[2]).to eq(" | | ") 
    expect(rows[3]).to eq("-----------") 
    expect(rows[4]).to eq(" | | ") 
    end 
+0

有什麼錯誤,特別是? – struthersneil

+0

'''NoMethodError: 對於RSpec :: ExampleGroups :: Board :: DisplayBoard:Class'''未定義的方法'capture'# –

+0

'#capture'是*用於從ActiveSupport可用的方法,但它看起來像它被棄用和刪除。所以這種方法是行不通的。 – struthersneil

回答

1

的問題是,#capture被廢棄和刪除。個人而言,我會將I/O從遊戲內容的生成中分離出來,因爲它更容易使用和測試。因此,而不是puts,只需建立一個包含您的電路板的字符串(每行末尾有一個\n)並測試其正確性。在實際的遊戲中,通過一個puts調用將板輸出到控制檯。

如果你確實想捕捉STDOUT,那麼有一種方法。 $stdout是包含對當前STDOUT流的引用的全局。默認情況下,它始終設置爲STDOUT,這是一個代表程序實際標準輸出的常量,但您可以將$stdout重定向到另一個IO流,例如StringIO對象。 puts將寫入任何$stdout而不是直接寫入STDOUT(這裏有一個微妙的區別!)。

$stdout = StringIO.new 
puts 'this is my output' 
captured_output = $stdout.string 
$stdout = STDOUT # restore it when you're done 

現在你有「這是我的輸出」(後面跟一個換行符)在captured_output抓獲。但是在那段時間你還會有其他的東西出現在標準輸出中,所以它並不理想(例如你的ruby控制檯中的控制檯輸出)。您應該用確保其始終恢復的方法包裝,例如

def capture() 
    $stdout = StringIO.new 
    yield 
    $stdout.string 
ensure 
    $stdout = STDOUT 
end 

您可以在塊中使用它,例如,

capture { puts 'xyz' } 
=> 'xyz\n' 

(但你有一個更簡單的生活,如果你忘記了這種做法,只是建立你的主板最多爲一個字符串。)

相關問題