javasocketstestingserverreadline

Why do my Java server tests pass when I add a System.out.println(in.readLine()) statement before the tests, but fail without that statement?


I'm working on implementing a server in Java to handle a multiplayer Minesweeper game. In trying to test my server to ensure that it responds correctly to legal client requests, I am finding that the tests only pass if I add a System.out.println(in.readLine()) statement after printing a particular client request to the output stream but before calling the tests themselves.

For example, one request a client can make is a "look" request, to see the current state of the board. I originally wrote a test for "look" as follows:

@Test(timeout = 10000)
    public void publishedTest() throws IOException {

        Thread thread = startMinesweeperServer("board5");

        Socket socket = connectToMinesweeperServer(thread);
        
        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        PrintWriter out = new PrintWriter(socket.getOutputStream(), true);

        out.println("look");
        assertEquals("- - - - - - -", in.readLine());
        assertEquals("- - - - - - -", in.readLine());
        assertEquals("- - - - - - -", in.readLine());
        assertEquals("- - - - - - -", in.readLine());
        assertEquals("- - - - - - -", in.readLine());
        assertEquals("- - - - - - -", in.readLine());
        assertEquals("- - - - - - -", in.readLine());

However, when I run the test like this, it fails and I get an error message saying that it expected [- - - - - - -] but got [].

However, when I add a print statement as follows:

@Test(timeout = 10000)
    public void publishedTest() throws IOException {

        Thread thread = startMinesweeperServer("board5");

        Socket socket = connectToMinesweeperServer(thread);

        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        PrintWriter out = new PrintWriter(socket.getOutputStream(), true);

        out.println("look");
        System.out.println(in.readLine());
        assertEquals("- - - - - - -", in.readLine());
        assertEquals("- - - - - - -", in.readLine());
        assertEquals("- - - - - - -", in.readLine());
        assertEquals("- - - - - - -", in.readLine());
        assertEquals("- - - - - - -", in.readLine());
        assertEquals("- - - - - - -", in.readLine());
        assertEquals("- - - - - - -", in.readLine());

the tests pass. Why would this be the case? Does the print statement just give the client more time to read the input from the server, or could there be something else going on? Happy to provide more snippets of my code if it would be helpful.


Solution

  • A shot in the dark: your server response starts with an unexpected empty line.

    The println part of System.out.println(in.readLine()); doesn't actually matter, and you'd get the same result with just in.readLine(), since it "consumes" the first line from the server. It's not a timing issue, because readLine() blocks until it receives a full line.

    You can fix this on the server, by removing whatever is sending the empty line, or by amending the test to account for it:

        out.println("look");
        assertEquals("", in.readLine()); // Add this line.
        assertEquals("- - - - - - -", in.readLine());
        assertEquals("- - - - - - -", in.readLine());
        assertEquals("- - - - - - -", in.readLine());
        assertEquals("- - - - - - -", in.readLine());
        assertEquals("- - - - - - -", in.readLine());
        assertEquals("- - - - - - -", in.readLine());
        assertEquals("- - - - - - -", in.readLine());