Pregunta

Lo que tengo ahora mismo

Tengo una instancia singleton de terceros en la que se basa mi clase bajo prueba y ese singleton está usando System.getenv (String) en su constructor. ¿Es posible burlarse de esta llamada?

Probé esto

Ejemplo de JMockIt

    new Expectations()
    {

        System mockedSystem;
        {
            System.getenv( "FISSK_CONFIG_HOME" ); returns( "." );
        }
    };

Pero me da un EXCEPTION_ACCESS_VIOLATION y bloquea la JVM.

¿Hay otra forma de establecer una variable de entorno del sistema para una prueba unitaria?

¿Fue útil?

Solución

En este caso, debe utilizar una burla parcial para que JMockit no redefina todo en la clase Sistema. La siguiente prueba pasará:

   @Test
   public void mockSystemGetenvMethod()
   {
      new Expectations()
      {
         @Mocked("getenv") System mockedSystem;

         {
            System.getenv("envVar"); returns(".");
         }
      };

      assertEquals(".", System.getenv("envVar"));
   }

Pronto implementaré una mejora para que no ocurran problemas como este al burlarse de las clases JRE. Debería estar disponible en la versión 0.992 o 0.993.

Otros consejos

PowerMock costuras para poder burlarse de las clases del sistema.

Su otra opción (suponiendo que no esté probando la unidad de la API de terceros) es crear una Fachada la API de terceros que tiene una interfaz agradable y fácil de imitar y hace que sus clases de prueba usen esto en lugar de lo real.

Oh, JMock también es compatible con esto:     paquete de prueba;

import static org.junit.Assert.*;

import mockit.*;
import mockit.integration.junit4.JMockit;

import org.junit.*;
import org.junit.runner.RunWith;

@RunWith(JMockit.class)
public class JMockItTest {

 @Test
 public void mockSystemGetEnv() {
  Mockit.setUpMocks(MockSystem.class); 

  assertEquals("Bye", System.getenv("Hello"));

 }

 @MockClass(realClass = System.class)
 public static class MockSystem {
  @Mock
  public static String getenv(String str) {
   return "Bye";
  }
 }

}

No puede cambiar el entorno, pero puede cambiar el acceso a él: simplemente envuelva la llamada a System.getenv () en un método o una clase auxiliar y luego simule eso.

[EDITAR] Ahora su problema es cómo cambiar el código de su biblioteca de terceros. La solución aquí es usar un descompilador de Java y arreglar la clase. Si lo desea, también puede enviar una solicitud de función. Agregue esa nueva clase a su conjunto de pruebas. Eso debería hacer que su IDE encuentre la clase para las pruebas.

Dado que el código de prueba no entra en producción, puede ejecutar sus pruebas y el código de producción usará la biblioteca original.

Hace un tiempo quería probar System.exit , y encontré una solución usando SecurityManager personalizado . Puede verificar que se está realizando la llamada y el argumento de la llamada, pero utilizando este método, no puede burlarse del valor de retorno de la llamada.

Una actualización en @ Rog & # 233; rio answer.

En mi caso con JMockit 1.25 tuve que hacerlo usando la API MockUp:

@Test
public void mockSystemGetenvMethod(){
    new MockUp<System>()
    {
        @Mock
        public String getenv(final String string) {
            return "";
        }
    };

    assertEquals(".", System.getenv("envVar"));
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top