Test de componente para un cliente TCP

De Dos Ideas.
Saltar a: navegación, buscar

Utilizando la librería Mockito, es posible crear un mock de una interfase y darle comportamiento a los distintos métodos de la misma. Teniendo en cuenta esto, podemos crear una clase con la funcionalidad de un servidor TCP que use esta interfase para procesar las peticiones, retornar una respuesta y de esta manera utilizarla en nuestros tests de componentes de un cliente TCP.

Ejemplo:

Server:

/**

* Servidor TCP/IP para utilizar en los test de componentes.
*/

public class ServerMock implements Runnable {

   /**
    * Interfase a mockear.
    */
   private RequestHandle handle;
   /**
    * Puerto
    */
   private int listenPort;
   /**
    * Tamaño maximo del mensaje.
    */
   private static final int TAMANIO_BUFFER = 1024;
   public ServerMock(RequestHandle serverRequestHandle) {
       this.handle = serverRequestHandle;
   }
   /**
    * Metodo para iniciar el server.
    * @throws InterruptedException 
    */
   public void start(int port) throws InterruptedException {
       this.listenPort = port;
       
       (new Thread(this)).start();
       // Esperamos hasta estar en el accept (notify).
       synchronized (this) {
           this.wait();
       }
   }
   @Override
   public void run() {
       try {
           ServerSocket serverSocket = new ServerSocket(listenPort);
           while (serverSocket != null) {
               Socket socket = null;
               System.out.println("Creando socket.");
               // Avisamos que estamos en el accept (sigue a partir del wait).
               synchronized (this) {
                   this.notify();
               }
               socket = serverSocket.accept();
               System.out.println("Conexión de: " + socket.getRemoteSocketAddress().toString());
               String peticion = null;
               String respuesta = null;
               while (true) {
                   byte[] request = new byte[TAMANIO_BUFFER];
                   try {
                       int tamanio = socket.getInputStream().read(request);
                       peticion = new String(request, 0, tamanio);
                       System.out.println("Reuqest: " + peticion);
                       // Invocamos la interface mockeada.
                       respuesta = (String) handle.handleRequest(peticion);
                       System.out.println("Response: " + respuesta.toString());
                       socket.getOutputStream().write(respuesta.getBytes());
                   } catch (IOException e) {
                       e.printStackTrace();
                       // Cerramos el socket para retornar -1.
                       socket.close();
                   }
                   // Volvemos al accept.
                   break;
               }
           }
       } catch (IOException ex) {
           ex.printStackTrace();
           System.exit(-1);
       }
   }

}

Test:

@RunWith(JUnit4.class) public class SocketClienteImplTest {

   /*
    * Cliente TCP.
    */
   private SocketClienteImpl instance = new SocketClienteImpl();;
   
   /*
    * Handler de peticiones para el server
    */
   private static RequestHandle handle;
   
   /*
    * Servidor TCP.
    */
   private static ServerMock serverMock;
   
   
   /*
    * Construimos e iniciamos el server.
    */
   @BeforeClass
   public static void setUp() throws InterruptedException {
       handle = mock(RequestHandle.class);
       serverMock = new ServerMock(handle);
       serverMock.start(4444);
   }


   @Test
   public void prueba_conCaracteres() throws IOException {
       
       doReturn("Hola Pablo").when(handle).handleRequest("Pablo");
       String respuesta = instance.send("localhost", 4444, "Pablo");
       Assert.assertEquals("Hola Pablo", respuesta);
   }
   
   @Test
   public void prueba_conNumeros() throws IOException {
       doReturn("100").when(handle).handleRequest("10");
       String respuesta = instance.send("localhost", 4444, "10");
       Assert.assertEquals("100", respuesta);
   }
   
   @Test(expected=RuntimeException.class)
   public void prueba_error() throws IOException {
       doThrow(new IOException()).when(handle).handleRequest("-1");
       instance.send("localhost", 4444, "-1");
       Assert.fail();
   }

}