1

I am a beginner in Java. I have built a client-server group chat application watching tutorials. I read a lot about unit tests and can implement in simple maths problems but i don't know how does it work out for complex codes. So I want to see a demo of that which will make it easy to understand testing for rest parts. One part of the code is the 'server' class and it is:

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
//import java.awt.event.*;

public class Server {

    private final ServerSocket s;

    public Server(ServerSocket serverSocket)
    {
        this.s = serverSocket;
        //this.display = display;
    }

    public void startServer() {
        try {
            // Listen for connections (clients to connect) on port 1234.
            while (!s.isClosed()) {
                // Will be closed in the Client Handler.
                Socket socket = s.accept();
                System.out.println("A new client has connected!");
                ClientHandler clientHandler = new ClientHandler(socket);
                Thread thread = new Thread(clientHandler);
                // The start method begins the execution of a thread.
                // When you call start() the run method is called.
                // The operating system schedules the threads.
                thread.start();
            }
        } catch (IOException e) {
            closeServerSocket();
        }
    }

    // Close the server socket gracefully.
    public void closeServerSocket() {
        try {
            if (s != null) {
                s.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // Run the program.
    public static void main(String[] args) throws IOException {
        ServerSocket s = new ServerSocket(1234);
        Server server = new Server(s);
        server.startServer();
    }

}

and the test I want to perform are:

import static org.junit.Assert.*;

public class ServerTeste {


    @org.junit.Test
    public void startServer() {



    }

    @org.junit.Test
    public void closeServerSocket() {
        f
        }
    }

    @org.junit.Test
    public void main() {
    }
}

NB: Apologies for any mistake because I am complete beginner.

Al Haqq
  • 11
  • 1
  • 2
    This is not really something you can "unit test". Those methods dont have a clearly defined input/output/goal. They just run forever and do something. Instead, test on the actual business logic a level beneath, for example the `ClientHandler` and whatever that one uses. Or do integration tests. Also, look into mocking for testing such complex objects. – Zabuzard Apr 05 '22 at 10:51
  • 1
    For example, what would you want the unit test for `startServer` to test? The actual business logic - thats wrong, that should be in the test of `ClientHandler`. The only thing that "would make sense" to test here, is that it can connect to multiple users and handle them individually without blocking each other. That requires you to mock `ServerSocket` and its `accept()` to create fake connections/clients. And it would require you to mock the actual streams returned by the `Socket` from `accept()` to actually observe whether they are polled simultanously. Quite heavy and probably not worth it. – Zabuzard Apr 05 '22 at 10:55
  • Style note: I would rename `startServer()` to be `runServer()`. Most people expect a method with "start" in its name to return promptly after kicking off something that happens "in the background." Your method doesn't _ever_ return. That sounds more like the behavior most people would expect from a "runXxxxxx()" method. – Solomon Slow Apr 05 '22 at 14:34

1 Answers1

0

Start the server in a separate thread, and connect to it like you would normally do

Antoniossss
  • 31,590
  • 6
  • 57
  • 99
  • That would provide some insight into whether `Server` behaves as expected, but that is not what most programmers mean when they say, "unit test." The usual expectation is that unit tests are automated, and they test the "unit" in isolation from other parts of the program. E.g., during a strict unit test of a `Server`-like class, no actual client socket, no actual thread, and no actual `ClientHandler` instance would be created. Instead, _test doubles_ (a.k.a., "mocks") of those objects would be created, and the test would verify the interactions between the `Server` class and the test doubles. – Solomon Slow Apr 05 '22 at 14:25