2012-05-17 22 views
11

necesito para probar el siguiente método con el cabo modificando el método en sí. El método crea un método POST para un servidor. Pero necesito hacer un caso de prueba que sea independiente del servidor.solicitud HTTP POST prueba de Java Junit

He probado un método similar antes de redirigirlo a un archivo local. Pero para eso estaba dando protocolo como archivo, nombre de host como localhost y puerto como -1.

Mi problema es que este método hace una publicación y se envía a HttpURLConnection y wr = new DataOutputStream (conn.getOutputStream()); no funcionará en un archivo txt local a través de http.

// el constructor

public HTTPConnector(String usr, String pwd, String protocol, 
      String hostname, int port) { 
     this.usr = usr; 
     this.pwd = pwd; 
     this.protocol = protocol; 
     this.hostname = hostname; 
     this.port = port; 

     // connect(); 
    } 

// el método que necesito para probar

public String doPost(String reference, String data) throws IOException { 
     URL url = null; 
     HttpURLConnection conn = null; 
     BufferedReader rd = null; 
     DataOutputStream wr = null; 
     InputStream is = null; 
     String line = null; 
     StringBuffer response = null; 

     url = new URL(protocol, hostname, port, reference); 
     conn = (HttpURLConnection) url.openConnection(); 

     conn.setRequestMethod("POST"); 

     conn.setRequestProperty("Authorization", "Basic dGVzdDphc2Rm"); 
     conn.setRequestProperty("Content-Type", "application/xml"); 

     conn.setUseCaches(false); 
     conn.setDoInput(true); 
     conn.setDoOutput(true); 

     // Send response 
     wr = new DataOutputStream(conn.getOutputStream()); 
     wr.writeBytes(data); 
     wr.flush(); 
     wr.close(); 

     // Get response 
     is = conn.getInputStream(); 
     rd = new BufferedReader(new InputStreamReader(is)); 
     response = new StringBuffer(); 
     while ((line = rd.readLine()) != null) { 
      response.append(line); 
      response.append('\r'); 
     } 
     rd.close(); 
     return response.toString(); 
    } 

// el método que podría poner a prueba

public String doGet(String reference) throws IOException { 
     connect(); 
     URL url = new URL(protocol, hostname, port, reference); 
     InputStream content = (InputStream) url.getContent(); 

     BufferedReader xml = new BufferedReader(new InputStreamReader(content)); 
     return xml.readLine(); 
    } 
+0

has mirado el uso de objetos simulados? – buymypies

+0

bueno, no va a nada local, así que me resulta difícil cómo redirigirlo. si puedo encontrar una manera de redirigirlo a un archivo o clase local, entonces podría darme una vuelta, pero la única forma en que puedo ver es crear un servidor/hilo local. pero eso significa que tengo que dirigir mis pruebas al servidor, para obtener datos allí y el servidor que necesita ser programado para que lo solicite y eso es mucho más que eficiente. – Gabain1993

Respuesta

6

Aquí es una prueba de muestra. Tenga en cuenta que las afirmaciones que hice son para fines de demostración, debe adaptarse a sus necesidades.

@RunWith(PowerMockRunner.class) 
@PrepareForTest({ toTest.class, URL.class, HttpURLConnection.class }) 
public class soTest { 
    /** 
    * test response. 
    */ 
    private static final String TEST_RESPONSE = "test\nresponse"; 

    /** 
    * test data. 
    */ 
    private static final String DATA = RandomStringUtils.randomAscii(125); 

    /** 
    * test port. 
    */ 
    private static final int PORT = 8080; 

    /** 
    * test hosts. 
    */ 
    private static final String HOSTNAME = "hostname"; 

    /** 
    * test protocol. 
    */ 
    private static final String PROTOCOL = "http"; 

    /** 
    * test reference. 
    */ 
    private static final String REFERENCE = "REFERENCE"; 

    /** 
    * URL mock. 
    */ 
    private URL url; 

    /** 
    * HttpURLConnection mock. 
    */ 
    private HttpURLConnection connection; 

    /** 
    * Our output. 
    */ 
    private ByteArrayOutputStream output; 

    /** 
    * Our input. 
    */ 
    private ByteArrayInputStream input; 

    /** 
    * Instance under tests. 
    */ 
    private toTest instance; 

    @Before 
    public void setUp() throws Exception 
    { 
     this.url = PowerMockito.mock(URL.class); 
     this.connection = PowerMockito.mock(HttpURLConnection.class); 

     this.output = new ByteArrayOutputStream(); 
     this.input = new ByteArrayInputStream(TEST_RESPONSE.getBytes()); 
     this.instance = new toTest(PROTOCOL, HOSTNAME, PORT); 

     PowerMockito.whenNew(URL.class).withArguments(PROTOCOL, HOSTNAME, PORT, REFERENCE).thenReturn(this.url); 
    } 

    @Test 
    public void testDoPost() throws Exception 
    { 
     PowerMockito.doReturn(this.connection).when(this.url).openConnection(); 
     PowerMockito.doReturn(this.output).when(this.connection).getOutputStream(); 
     PowerMockito.doReturn(this.input).when(this.connection).getInputStream(); 

     final String response = this.instance.doPost(REFERENCE, DATA); 

     PowerMockito.verifyNew(URL.class); 
     new URL(PROTOCOL, HOSTNAME, PORT, REFERENCE); 

     // Mockito.verify(this.url).openConnection(); // cannot be verified (mockito limitation) 
     Mockito.verify(this.connection).getOutputStream(); 
     Mockito.verify(this.connection).setRequestMethod("POST"); 
     Mockito.verify(this.connection).setRequestProperty("Authorization", "Basic dGVzdDphc2Rm"); 
     Mockito.verify(this.connection).setRequestProperty("Content-Type", "application/xml"); 
     Mockito.verify(this.connection).setUseCaches(false); 
     Mockito.verify(this.connection).setDoInput(true); 
     Mockito.verify(this.connection).setDoOutput(true); 
     Mockito.verify(this.connection).getInputStream(); 

     assertArrayEquals(DATA.getBytes(), this.output.toByteArray()); 
     assertEquals(TEST_RESPONSE.replaceAll("\n", "\r") + "\r", response); 
    } 
} 


@Data 
public class toTest { 
    private final String protocol, hostname; 

    private final int port; 

    public String doPost(String reference, String data) throws IOException 
    { 
     // your method, not modified 
    } 
} 

dependencias:

  • Commons-Lang 2,5
  • powermock-api-Mockito 1.4.11
  • powermock-module-junit4 1.4.11
  • junit 4,10
  • lombok 0.11.0 en la clase probada
+1

parece una buena solución, pero me sale un error y no sé cómo resolverlo, quizás pueda arrojar algo de luz: el tipo org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner no se puede resolver. Es indirectamente \t al que se hace referencia desde los archivos .class necesarios – Gabain1993

+0

Esta clase es proporcionada por 'powermock-module-junit4', eso es extraño. Debes verificar tu classpath –

5

Si usted no tiene la oportunidad de refactorizar el método bajo prueba, a continuación, un nuevo enfoque sería burlarse de la HttpUrlConnection que utiliza. De primera mano esto parece ser difícil porque el HttpUrlConnection no se pasa como parámetro. Sin embargo, puede controlar esto controlando la conexión devuelta desde url.openConnection.

Esto se rige por el controlador de protocolo registrado en java.net.URL para el protocolo que pasa al constructor. El truco es registrar un nuevo controlador de protocolo (ver Java - Registering custom URL protocol handlers para más detalles).

Su nuevo controlador de protocolo debe devolver un HttpUrlConnection simulado que puede utilizar en su prueba.

Cuestiones relacionadas