2016-12-20 6 views
1

minitestを使ってcase文のテストを書こうとしています。私はそれぞれの "いつ"別々のテストを書く必要がありますか?私は以下の私のコードを含めた。今は文を入れるだけですが、最終的にはユーザーを別の方法にリダイレクトします。ありがとう!Rubyでcase文のテストを書く

require 'pry' 
require_relative 'messages' 

class Game 
    attr_reader :user_answer 

    def initialize(user_answer = gets.chomp.downcase) 
    @user_answer = user_answer 
    end 

    def input 
    case user_answer 
    when "i" 
     puts "information" 
    when "q" 
     puts "quitter" 
    when "p" 
     puts "player play" 
    end 
    end 
end 
+0

はい、このコードをすべてのパスをテストするには、各 'ときのためにテストを記述する必要があります'。 – slim

+2

これは実際に考案された例です。ほとんどの場合、一連のイベントが実行されるいくつかの運動事例を作成する必要があります。時にはこれらが非常に複雑になり、簡単にするためにJSONまたはYAMLとして保存された一連のケースファイルで入力と期待される出力を指定する必要があります。可能なすべてのパスを実行するだけでなく、空の文字列、 'nil'値、' $ 'のような無効な入力のような無効なパスの代表的なサンプルも必ず実行してください。 – tadman

答えて

4

This answerが役に立ちます。それにもかかわらず、私はあなたの状況にそれを適用する1つの方法を投稿します。ゲームを初期化するときに@phortxが示唆するように、デフォルトのユーザー入力を関連する文字列で上書きします。そして、assert_outputを使用することによって、私たちのようなものを行うことができます...

#test_game.rb 
require './game.rb'   #name and path of your game script 
require 'minitest/autorun' #needed to run tests 

class GameTest < MiniTest::Test 

    def setup 
    @game_i = Game.new("i") #overrides default user-input 
    @game_q = Game.new("q") 
    @game_p = Game.new("p") 
    end 

    def test_case_i 
    assert_output(/information\n/) {@game_i.input} 
    end 

    def test_case_q 
    assert_output(/quitter\n/) {@game_q.input} 
    end 

    def test_case_p 
    assert_output(/player play\n/) {@game_p.input} 
    end 
end 

テストを実行し

$ ruby test_game.rb 
#Run options: --seed 55321 

## Running: 

#... 

#Finished in 0.002367s, 1267.6099 runs/s, 2535.2197 assertions/s. 

#3 runs, 6 assertions, 0 failures, 0 errors, 0 skips 
+1

'assert_output'は、この概念をテストする最も機能的な方法です。なぜなら、戻り値に依存することができないからです(常にゼロになります) – engineersmnky

2

各ケースブランチをテストする必要があります。 RSpecのを経由して、それはそのように動作します:

describe Game do 
    subject { Game } 

    describe '#input' do 
    expect_any_instance_of(Game).to receive(:puts).with('information') 
    Game.new('i').input 

    expect_any_instance_of(Game).to receive(:puts).with('quitter') 
    Game.new('q').input 

    expect_any_instance_of(Game).to receive(:puts).with('player play') 
    Game.new('p').input 
    end 
end 

しかしputsをテストする醜いであるという事実により、あなたはそのような何かにあなたのコードをリファクタリングする必要があります

require 'pry' 
require_relative 'messages' 

class Game 
    attr_reader :user_answer 

    def initialize(user_answer = gets.chomp.downcase) 
    @user_answer = user_answer 
    end 

    def input 
    case user_answer 
    when "i" 
    "information" 
    when "q" 
     "quitter" 
    when "p" 
     "player play" 
    end 
    end 

    def print_input 
    puts input 
    end 
end 

その後、あなたはRSpecのを経由してテストすることができます:

describe Game do 
    subject { Game } 

    describe '#print_input' do 
    expect_any_instance_of(Game).to receive(:puts).with('quitter') 
    Game.new('q').print_input 
    end 

    describe '#input' do 
    expect(Game.new('i').input).to eq('information') 
    expect(Game.new('q').input).to eq('quitter') 
    expect(Game.new('i').input).to eq('player play') 
    expect(Game.new('x').input).to eq(nil) 
    end 
end 
+0

'user_answer'は' attr_reader:user_answer'によって作成されたメソッドを参照します。 '@ user_answer'を返します。 –

+0

はい、そうです、私はそれを見落としました。 – phortx

+3

ここで正しいところですが、 'puts'が' nil'を返すので、これはうまくいきません。元のコードは簡単にテストすることはできませんが、よりフレンドリーになるように修正することができます。 – tadman