2017-09-17 7 views
1

私は変数が少ないクラスを持っています。これらの変数はユーザーから入力されます。テストケースを作成しようとしていますので、クラスオブジェクトを初期化しました。問題は、どのように私はユーザーの入力を必要とする変数に入力を送信することができますです。ユニットテストへのスキャナ入力の送信

これはこれは、任意の助けをいただければ幸い

package src; 

import static org.junit.Assert.*; 

import java.io.ByteArrayInputStream; 
import java.io.InputStream; 

import org.junit.Test; 
public class MainTest { 

    @Test 
    public void testInputReader() { 
     Main Obj = new Main(); 
     String input = "50"; 
     InputStream in = new ByteArrayInputStream(input.getBytes()); 
     System.setIn(in); 
     input = "40"; 
     in = new ByteArrayInputStream(input.getBytes()); 
     System.setIn(in); 
     input = "25"; 
     in = new ByteArrayInputStream(input.getBytes()); 
     System.setIn(in); 

     input = "300"; 
     in = new ByteArrayInputStream(input.getBytes()); 
     System.setIn(in); 

     assertEquals("8 books, $9 remaining", Obj.offerFunction()); 

    } 

} 

私のテストクラスである

package src; 

import java.util.Scanner; 

public class Main { 
    int initialBookPrice; 

    int discountPrice; 

    int basePrice ; 

    int budget ; 
    public static void main(String[] args) { 
     Main Obj = new Main(); 

      Obj.initialBookPrice = Obj.inputReader("Initial Book Price"); 

      Obj.discountPrice = Obj.inputReader("Discount Price"); 

      Obj.basePrice= Obj.inputReader("Base Price"); 

      Obj.budget= Obj.inputReader("Budget"); 

      if (Obj.budget < Obj.initialBookPrice) { 
       System.out.printf("0 Books, $%s remaining", Obj.budget); 
      } else if (Obj.budget == Obj.initialBookPrice) { 
       System.out.printf("1 Book, $0 remaining"); 
      } else { 
       System.out.println(Obj.offerFunction()); 
      } 



    } 

    public int inputReader(String variableName) { 
     System.out.printf("Please enter the %s: ",variableName); 
     Scanner scanner = new Scanner(System.in); 
     boolean flag = true; 
     int n = 0; 
     while (flag) { 
      n = Integer.parseInt(scanner.next()); 
      if (n >= 0) { 
       break; 
      }else{ 
       System.out.printf("Please enter a valid Positive %s",variableName); 
       System.out.printf("\nPlease enter the %s: ",variableName); 
      } 

     } 
     return n; 


    } 

    public String offerFunction() { 
     int diffPrice = this.initialBookPrice - this.basePrice; 
     int numberOfBooks = 0; 
     int tempBudget = this.budget; 
     int remaining = 0; 
     for (int i = this.initialBookPrice; i >= diffPrice; i= i - this.discountPrice) { 
      numberOfBooks+=1; 
      tempBudget -= i; 
     } 
     numberOfBooks += tempBudget/this.basePrice; 
     remaining = tempBudget % this.basePrice; 
     return String.format(" %s books, $%s remaining", numberOfBooks,remaining); 

    } 
    } 

私のクラスです。

+0

すでにSystem.setIn(in)を使用しています。入力をフィードする。あなたはどんな問題に直面していますか? –

+2

変数名が大文字で始まらないようにしてください。実際には大文字で始まるクラス名と混同します。 'Obj'という名前は' String'や 'InputStream'のようなクラスのように見えますが、実際は変数です。 – Progman

+0

@ Sachin Aggarwal、私はコードを実行するとき、それは単にパスまたは失敗を言わずに実行されています –

答えて

1

のようなライブラリを使用する場合がありますモックを作成するには、次のテストで

Main Obj = new Main(); 
    String input = "50 40 25 300"; 
    InputStream in = new ByteArrayInputStream(input.getBytes()); 
    System.setIn(in); 
    assertEquals(50, Obj.inputReader("anyVariable")); 

は、あなたがあなた自身のストリームにSystem.inを交換するだけで働いていたことがわかります良い。

あなたは、メインプログラムの全体の機能をテストしたい場合、あなたはおそらく作るべきである自身の方法、多分printPrices():スキャナは、クラス内のフィールドに昇格されていることを

public void printPrice() { 
    scanner = new Scanner(System.in); 

    initialBookPrice = inputReader("Initial Book Price"); 

    discountPrice = inputReader("Discount Price"); 

    basePrice= inputReader("Base Price"); 

    budget= inputReader("Budget"); 

    if (budget < initialBookPrice) { 
     System.out.printf("0 Books, $%s remaining", budget); 
    } else if (budget == initialBookPrice) { 
     System.out.printf("1 Book, $0 remaining"); 
    } else { 
     System.out.println(offerFunction()); 
    } 

} 

注意。テストメソッドに

String input = "50 40 25 300"; 
InputStream in = new ByteArrayInputStream(input.getBytes()); 
System.setIn(in); 
Obj.printPrice(); 

を挿入するとうまくいきます。

しかし、テスト容易性の観点からは、実際に何かをアサートできるので、そのメソッドにStringを返す方が良いでしょう。しかし、それは別の問題です...

1

一般的にユニットテストの内部クラス(SystemやScannerなど)はJVM自身でテストされており、正常に動作すると想定しています。

あなたのメソッドinputReaderでは、ユーザーの入力を待ちます。ユニットテストでその動作をシミュレートするには、いわゆる "モック"を作成します。テストは何か起こったが、まったく起こらなかったと思うようにします(ユーザー入力など)。非常に単純化された説明ですが、あなたはそのアイディアを得ます。

あなたが挿入する場合は、Mockito