0

I am currently trying to Junit test a game for a Uni assignment. Below is an example of the kind of methods I am trying to test.

public static int choosePlayers(int num) {
    while (validPlayerNumber == false) {
        try {
            System.out.print("Please enter Number of players (2-4)\n> ");
            num = in.nextInt();
            switch (num) {
            case 2:
                validPlayerNumber = true;
                numberPlayers = num;
                System.out.println(numberPlayers + " players selected");
                break;
            case 3:
                validPlayerNumber = true;
                numberPlayers = num;
                System.out.println(numberPlayers + " players selected");
                break;
            case 4:
                validPlayerNumber = true;
                numberPlayers = num;
                System.out.println(numberPlayers + " players selected");
                break;
            default:
                throw new IllegalArgumentException("Sorry, that is not a valid selection.");
                // System.out.println("Sorry, that is not a valid selection.");
            }
        } catch (InputMismatchException ex) {
            // log the exception
            System.out.println("Problem with input : " + ex.toString());
            continue;
        }
    }
    return numberPlayers;
}

I am using the following test class to test this:

/**
 * @throws java.lang.Exception
 */
@Before

public void setUp() throws Exception {
    num1 =1;
    num2= 2;
    num4 = 4;
    num3 = 3;
    num5 = 5;
    game= new Game();
}

@Test
public void testchoosePlayers2() {

 System.out.println("Testing choosingPlayers 2");
Scanner scanner = new Scanner (System.in);
 int expected = scanner.nextInt();
  int actual = game.choosePlayers(num2);
 assertEquals(expected, actual);
 System.out.println("Test finsihed");
}


@Test
public void testchoosePlayers3() {
    System.out.println("Testing choosingPlayers 3");
    Scanner scanner = new Scanner (System.in);
    int expected = scanner.nextInt();
    int actual = game.choosePlayers(num3);
     assertEquals(expected, actual);
     System.out.println("Test finsihed");

}


@Test
public void testchoosePlayers4() {
    System.out.println("Testing choosingPlayers 4");
    Scanner scanner = new Scanner (System.in);
    int expected = scanner.nextInt();
    int actual = game.choosePlayers(num4);
     assertEquals(expected, actual);
     System.out.println("Test finsihed");

}

Every time I try and run this test only the first test will run and the scanner is not re-prompted for the subsequent 2. Is there any way around this? I would greatly appreciate any advice concerning this issue or for a better/more efficient way to test the above method .

1 Answers1

1

Your purpose here is to test that method returns correct values with provided input parameters. If you scan incorrect value test will fail. So instead of scanning expected value just put expected value to the assertion. Also you don't need separate tests here, since you test the same functionality.

To simulate input you will need to replace System.in with your own input stream. See JUnit: How to simulate System.in testing? for details.


    private final InputStream systemIn = System.in;
    private ByteArrayInputStream testIn;

    @After
    public void resetSystemIn() {
        System.setIn(systemIn);
    }

    private void inputData(String data) {
        testIn = new ByteArrayInputStream(data.getBytes());
        System.setIn(testIn);
    }

    @Test
    public void testchoosePlayers() {
        System.out.println("Testing choosingPlayers 2");
        inputData("2");
        int actual = game.choosePlayers(num2);
        assertEquals(num2, actual);
        System.out.println("Testing choosingPlayers 3");
        inputData("3");
        actual = game.choosePlayers(num3);
        assertEquals(num3, actual);
        System.out.println("Testing choosingPlayers 4");
        inputData("4");
        actual = game.choosePlayers(num4);
        assertEquals(num4, actual);
        System.out.println("Test finsihed");
    }
devmind
  • 344
  • 2
  • 10
  • Thank you for your advice, unfortunately when I run the test, the scanner from the method being tested Is still called and asks for an number input, negating the values I set in the test data (num1 , num2 etc). Do you have any advice concerning this? –  Mar 08 '19 at 18:40
  • `int num` parameter confused me. See answer updated. – devmind Mar 08 '19 at 19:21