将扫描仪输入发送到单元测试

时间:2017-09-17 20:18:30

标签: java junit

我有一个变量很少的类。这些变量从用户那里获得输入。我正在尝试编写测试用例,所以我已经初始化了类对象。问题是如何将输入发送到需要用户输入的变量。

这是我的班级

  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);

    }
    }

这是我的测试类

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());

    }

}

任何帮助将不胜感激。提前致谢

2 个答案:

答案 0 :(得分:2)

如果您插入:

    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());
    }

}

请注意,Scanner会提升为班级中的某个字段。如果现在你插入

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

在你的测试方法中,它会正常工作。

但是,从可测试性的角度来看,让该方法返回一个String会更好,因为那时你可以实际断言一些东西。但那是另一回事......

答案 1 :(得分:1)

您通常不希望对内部类(如系统或扫描程序)进行单元测试,它们是由JVM本身测试的,我们假设它们正常工作。

在方法inputReader中等待用户输入。要在单元测试中模拟该行为,您需要创建一个所谓的“模拟”。它使你的测试思考,发生了一些事情,但它根本没有发生(例如用户输入)。非常简化的解释,但你明白了。

要创建模拟,您可能需要使用像Mockito

这样的库