Java 如何测试System.out.println();嘲弄

Java 如何测试System.out.println();嘲弄,java,unit-testing,mockito,Java,Unit Testing,Mockito,你好,我必须练习如何使用Mockito。有人能告诉我如何使用mock对象来测试基于控制台的输出测试吗 Random rand = new Random(); int number = 1+rand.nextInt(100); // random number 1 to 100 Scanner scan = new Scanner(System.in); for (int i=1; i<=10; i++){ // for l

你好,我必须练习如何使用Mockito。有人能告诉我如何使用mock对象来测试基于控制台的输出测试吗

Random rand = new Random();
int number = 1+rand.nextInt(100);              // random number 1 to 100
Scanner scan = new Scanner(System.in);

for (int i=1; i<=10; i++){                     // for loop from 1 to 10
    System.out.println(" guess "+i+ ":");``
    int guess = scan.nextInt();
    //if guess is greater than number entered 
    if(guess>number)
        System.out.println("Clue: lower");
    //if guess is less than number entered 
    else if (guess<number )
        System.out.println("lue: Higher");
    //if guess is equal than number entered 
    else if(guess==number) {
        System.out.println("Correct answer after only "+ i + " guesses – Excellent!");
        scan.close();
        System.exit(-1);
    }

}

System.out.println("you lost" + number);
scan.close();
Random rand=new Random();
整数=1+rand.nextInt(100);//随机数1到100
扫描仪扫描=新扫描仪(System.in);
对于(整数i=1;整数)
System.out.println(“线索:下”);
//如果猜测小于输入的数字

否则,如果(猜测首先-对System.exit()的调用将破坏您的测试

第二,模拟
系统
类不是一个好主意。将System.out重定向到一个假的或存根会更有意义

从System.in三读资料也很难在测试中完成

除此之外:为了可读性,我还随意减少了代码:

public class WritesOut {

    public static void doIt() {
           System.out.println("did it!");
    }

}
测试应测试行是否打印到System.out:

import static org.junit.Assert.*;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;

import org.junit.Test;

public class WritesOutTestUsingStub {

    @Test
    public void testDoIt() throws Exception {
        //Redirect System.out to buffer
        ByteArrayOutputStream bo = new ByteArrayOutputStream();
        System.setOut(new PrintStream(bo));
        MockOut.doIt();
        bo.flush();
        String allWrittenLines = new String(bo.toByteArray()); 
        assertTrue(allWrittenLines.contains("did it!"));
    }

}

首先-调用System.exit()将中断测试

第二,模拟
系统
类不是一个好主意。将System.out重定向到一个假的或存根会更有意义

从System.in三读资料也很难在测试中完成

除此之外:为了可读性,我还随意减少了代码:

public class WritesOut {

    public static void doIt() {
           System.out.println("did it!");
    }

}
测试应测试行是否打印到System.out:

import static org.junit.Assert.*;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;

import org.junit.Test;

public class WritesOutTestUsingStub {

    @Test
    public void testDoIt() throws Exception {
        //Redirect System.out to buffer
        ByteArrayOutputStream bo = new ByteArrayOutputStream();
        System.setOut(new PrintStream(bo));
        MockOut.doIt();
        bo.flush();
        String allWrittenLines = new String(bo.toByteArray()); 
        assertTrue(allWrittenLines.contains("did it!"));
    }

}

我不会使用mockito来测试这个,我会将System.out(via)设置为一个备份的PrintStream并进行检查

如果要进行单元测试,还需要删除该系统。退出

我要看的两件事是模拟和。我还要看一下逻辑和显示的分离。你并不真正关心输出的是什么,而是逻辑理解,输入X得到的是输出Y

为什么?如果你模拟System.out(你可以通过System.setOut来做),你最终会证明你可以编写模拟验证,但其他的就很少了。测试代码最终会变得非常脆弱,很难理解。 通过使用ByteArrayOutputStream,您可以以非常简单的方式获得输出

Random和Scanner是更简单的外部系统,不会给您留下如此脆弱的代码

然而,正如我所说,我将把游戏逻辑与用户输入分开。例如,我有一个理解游戏的类

class Game
   // implementation
   Game(int startingNumber, int attemptsAllowed);

   public {WON,HIGHER,LOWER,LOST} go(int guess) { ... }
}
然后,可以轻松地测试该对象,并与(更难测试的)用户界面完全隔离


当你想测试用户界面时,你可以模拟这个对象,以确保它总是返回你想要的东西,它也会返回。

我不会使用mockito来测试这个。我会将System.out(via)设置为一个备份的PrintStream并检查它

如果要进行单元测试,还需要删除该系统。退出

我要看的两件事是模拟和。我还要看一下逻辑和显示的分离。你并不真正关心输出的是什么,而是逻辑理解,输入X得到的是输出Y

为什么?如果你模拟System.out(你可以通过System.setOut来做),你最终会证明你可以编写模拟验证,但其他的就很少了。测试代码最终会变得非常脆弱,很难理解。 通过使用ByteArrayOutputStream,您可以以非常简单的方式获得输出

Random和Scanner是更简单的外部系统,不会给您留下如此脆弱的代码

然而,正如我所说,我将把游戏逻辑与用户输入分开。例如,我有一个理解游戏的类

class Game
   // implementation
   Game(int startingNumber, int attemptsAllowed);

   public {WON,HIGHER,LOWER,LOST} go(int guess) { ... }
}
然后,可以轻松地测试该对象,并与(更难测试的)用户界面完全隔离


当你想测试用户界面时,你可以模拟这个对象,以确保它总是返回你想要的东西,它也会返回你想要的东西。

到目前为止你尝试了什么?熟悉Mockito(或任何东西)的最佳方法是通过尝试使用它。我投票将此问题作为离题结束,因为。请查看Mockito教程并提出一个关于使用Mockito的具体问题。到目前为止,您尝试了什么?熟悉Mockito(或任何内容)的最佳方法是通过尝试使用它。我投票将这个问题作为离题题来结束,因为。请查看Mockito教程,并提出一个关于使用Mockito的具体问题。你能描述一下我如何使用mokito在扫描仪和Random上进行测试吗?我的目标是学习mokito框架,这只是我选择的一个随机任务。提前感谢学习mockit我觉得“随机任务”并不是一个很好的方法。你会为这个类编写什么测试?为什么要模拟(或存根)Random和Scanner?你能描述一下我如何使用mokito对Scanner和Random进行测试吗?我的目标是学习mokito框架,这只是我选择的一项随机任务。提前感谢通过“Random tasks”学习mockito,我觉得这不是一个很好的方法。你会为这门课编写什么测试?你为什么想要模仿(或存根)Random和Scanner?第二-无法模拟系统类。但您可以重定向。很抱歉,这是错误的,您可以将System.out设置为模拟类。这将是愚蠢的,但您可以做到。您也可以模拟。我不会,但您可以。当测试是多线程时也不是很好。如果其他线程想要打印1,您将丢失th的输出ose线程2.您的测试可能/将在@Brice上打破良好的点,您最好在测试中注入PrinterStream并通过System.out,以及内存版本(或将输出与逻辑分离)第二,无法模拟系统类。但您可以重定向。很抱歉,这是错误的,您可以将System.out设置为模拟类。这将是愚蠢的,但您可以做到。您也可以模拟。我不会,但您可以。当测试是多线程时,也不是很好。如果其他线程想要打印1。您将丢失这些线程的输出2。您的测试可能/将在@Brice突破良好点,您最好注入PrinterStream和passin