2017-08-10 2 views
1

Ich versuche eine Spezifikation zu schreiben, um die Anzeige eines Tic-Tac-Toe Board zu testen. Ich verwende die Methode capture, aber es wirft einen Fehler, wenn ich die Spezifikation ausführen. Ich verwende Capture, um die Ausgabe eines Methodenaufrufs zu erhalten. https://apidock.com/rails/Kernel/capture Hier ist meine Methode:undefined Methode `Capture 'für RSpec

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 

Hier ist mein Rspec Test:

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

Was der Fehler ist, speziell? – struthersneil

+0

'' 'NoMethodError: undefinierte Methode' Capture 'für RSpec :: ExampleGroups :: Board :: DisplayBoard: Class''' –

+0

'# capture' war eine Methode, die * von ActiveSupport * verwendet wurde, aber es sieht so aus es wurde veraltet und entfernt. Dieser Ansatz wird also nicht funktionieren. – struthersneil

Antwort

1

Das Problem ist, dass #capture veraltet und entfernt wurde.

Persönlich würde ich I/O von der Generierung des Spielinhalts trennen, weil es einfacher ist, damit zu arbeiten und zu testen. Erstellen Sie also statt puts einfach eine Zeichenfolge, die Ihre Karte enthält (mit einer \n am Ende jeder Zeile) und testen Sie diese auf Korrektheit. Im aktuellen Spiel geben Sie die Karte mit einem puts Aufruf an die Konsole aus.

Wenn Sie wirklich STDOUT erfassen möchten, gibt es einen Weg. $stdout ist ein globaler Verweis auf den aktuellen STDOUT-Stream. Standardmäßig ist dies immer auf STDOUT eingestellt, eine Konstante, die den tatsächlichen STDOUT des Programms darstellt, aber Sie können $stdout in einen anderen IO-Stream umleiten, zum Beispiel ein StringIO Objekt. puts wird auf was auch immer schreiben $stdout bezieht sich auf direkt an STDOUT schreiben (es gibt einen feinen Unterschied gibt!).

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

Jetzt haben Sie 'das ist mein Ausgang' (gefolgt von einem Newline-Zeichen) in captured_output erfasst. Aber Sie haben auch noch etwas anderes, das in dieser Zeit zu STDOUT ging, also ist es nicht ideal (z. B. Konsolenausgabe in Ihrer Ruby-Konsole). Sie sollten das in eine Methode einbetten, die sicherstellt, dass es immer wiederhergestellt wird, z.

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

können Sie diese verwenden, um mit einem Block, z.B.

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

(Aber Sie werden ein leichteres Leben haben, wenn Sie diesen Ansatz vergessen und nur das Board bauen als String auf.)

Verwandte Themen