1

I'm very new to JUnit and Unit Testing and have a question regarding mocking user input to the Scanner object. I have the following code that I would like to test. Very Basic.

Run Code

import java.util.Scanner;

public class MyGame{
    public MyGame() {
        Scanner response = new Scanner(System.in);

        int game;

        System.out.println("Enter a game.");
        System.out.println("Press 1 for Super Awesome Bros.");
        System.out.println("Press 2 for a Random game.");

        game = response.nextInt();

        if (game == 1){
            System.out.println("Super Awesome Bros.");
    }
  }
}

Here is my Testcase

import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.junit.contrib.java.lang.system.StandardOutputStreamLog;
import org.junit.contrib.java.lang.system.TextFromStandardInputStream;
import static org.junit.Assert.assertThat;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.contrib.java.lang.system.TextFromStandardInputStream.*;

@RunWith(JUnit4.class)
    public class Testsuite {

      @Rule
      public final StandardOutputStreamLog out = new StandardOutputStreamLog();

      @Rule
      public final TextFromStandardInputStream in = emptyStandardInputStream();

  @Test
  public void printOutput() {
    in.provideText("1\n");
    new MyGame();
    assertThat(out.getLog(), containsString("Super Awesome Bros."));
  }

}

So in my Testcase, I'm trying to mock the input to be 1 so I can receive the expected output. But for some reason my code passes regardless of what the output is. I'm not sure what I'm doing wrong. The test should fail if the output is not what's expected. Can someone spot the issue? Again, I'm just trying to get a grasp of JUnit and Unit Testing. I'm use to testing in Python mostly. Thanks to everyone in advanced.

Stefan Birkner
  • 24,059
  • 12
  • 57
  • 72
salce
  • 409
  • 1
  • 12
  • 28
  • 2
    Install [IntelliJ IDEA](https://www.jetbrains.com/idea/), right-click the test name and select "Debug", then you'll be able to trace the execution and easily find out why it fails/succeeds. Also read about debugging if you unsure how to do that: https://www.jetbrains.com/help/idea/2016.1/debugging.html – user3707125 Apr 08 '16 at 23:48
  • Do you mean that the test is still green if you change the first line of the test to `in.provideText("2\n");`? – Stefan Birkner Apr 10 '16 at 17:57
  • How do you run your test? – Stefan Birkner Apr 10 '16 at 17:58
  • 1
    I think that System.out actually receives the text Super Awesome Bros. in the following line: System.out.println("Press 1 for Super Awesome Bros.");, so the test will always pass. – keuleJ Apr 10 '16 at 18:03
  • Is it even a good idea to hard-wire a dependency on `System.in` in a class? I'd rather provide an input stream via a constructor, so the testing code can then use `ByteArrayInputStream` or something. – Sergei Tachenov Apr 10 '16 at 18:46

1 Answers1

0

Your test is always passing because you're always writing the String "Press 1 for Super Awesome Bros.". Therefore the check

assertThat(out.getLog(), containsString("Super Awesome Bros."));

matches always.

By the way you don't have to write @RunWith(JUnit4.class). You can remove that line.

Stefan Birkner
  • 24,059
  • 12
  • 57
  • 72