Clase bajo prueba:

public class SystemCaller {
  public String callSystem() {
    return System.getenv("test-this");
  }
}

Prueba 1:

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;

@RunWith(PowerMockRunner.class)
@PrepareForTest({SystemCaller.class, System.class})
public class SystemTestOne {

    @Before
    public void start() throws Exception {
        PowerMockito.mockStatic(System.class);
        PowerMockito.when(System.getenv("test-this")).thenReturn("hello-one");
    }

    @After
    public void stop() {}

    @Test
    public void verifySystemTestOne() throws Exception {
        assertThat(new SystemCaller().callSystem(), is("hello-one"));
    }
}

Prueba 2:

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;

@RunWith(PowerMockRunner.class)
@PrepareForTest({SystemCaller.class, System.class})
public class SystemTestTwo {

    @Before
    public void start() throws Exception {
        PowerMockito.mockStatic(System.class);
        PowerMockito.when(System.getenv("test-this")).thenReturn("hello-two");
    }

    @After
    public void stop() {}

    @Test
    public void verifySystemTestTwo() throws Exception {
        assertThat(new SystemCaller().callSystem(), is("hello-two"));
    }
}

Si se ejecuta individualmente, cada prueba pasa por sí sola. Sin embargo, cuando ejecuto las pruebas all , las pruebas fallan. Y el error varía. A veces, la aserción espera hello-two, pero obtiene hello-one. En otras ocasiones, callSystem() solo devuelve null.

¿Hay algún problema de configuración aquí? ¿O es porque me estoy burlando de un método static (en la clase System en este caso) que está causando el problema?

Mis dependencias:

      "org.apache.commons" % "commons-lang3" % "3.5" ::
      "com.squareup.okhttp3" % "okhttp" % "3.6.0" ::
      "com.google.code.gson" % "gson" % "2.8.0" ::
      "com.novocode" % "junit-interface" % "0.8" % "test->default" ::
      "junit" % "junit" % "4.12" % "test" ::
      "org.hamcrest" % "hamcrest-core" % "1.3" % "test" ::
      "org.hamcrest" % "hamcrest-library" % "1.3.RC2" % "test" ::
      "com.squareup.okhttp3" % "mockwebserver" % "3.8.0" % "test" ::
      "org.powermock" % "powermock-core" % "1.6.6" % "test" ::
      "org.powermock" % "powermock-api-mockito" % "1.6.6" % "test" ::
      "org.powermock" % "powermock-module-junit4" % "1.6.6" % "test" ::

ACTUALIZACIÓN 1:

OK, la sugerencia de @ kevin-welker, para usar EnvironmentVariables realmente funcionó. Sin embargo, veo un problema extraño en el que, cuando ejecuto las pruebas JUnit desde Intellij IDEA (usando JUnit Run Configuration ), todo funciona, pero cuando los ejecuto a través de sbt (a través de ./sbt test) fallan con el mismo error :(.

Estoy aprovechando https://github.com/sbt/junit-interface para ejecutar estos pruebas, pero parece que no puede hacer que funcionen.

ACTUALIZACIÓN 2:

¡Bien! Gracias a @ kevin-welker y @ stefan-birkner, ¡hice que las pruebas funcionen como se esperaba! Como solo necesito ejecutar un puñado de pruebas, y son realmente rápidas, ¡estoy bien perdiendo el paralelismo!

1
kodeninja 18 oct. 2017 a las 19:25

3 respuestas

La mejor respuesta

Hay una micro biblioteca para ayudar con las clases de sistemas de burla llamada Reglas del sistema. El uso es tan simple como

@Rule
public final ProvideSystemProperty myPropertyHasMyValue
    = new ProvideSystemProperty("MyProperty", "MyValue");
2
Kevin Welker 18 oct. 2017 a las 16:48

No puede burlarse de System y otras clases del sistema. Por lo general, es por eso que crea contenedores como su clase SystemCaller que solo contendrá la lógica no comprobable y que puede burlarse de dónde se usan en el código.

Más información aquí: https://github.com/powermock/powermock/wiki/Mock- Sistema

0
Nyamiou The Galeanthrope 18 oct. 2017 a las 16:32

Puede probar PowerMockito.doCallRealMethod().when(System.class); después de su prueba (@After o @AfterClass), debería restablecer la simulación de System.class.

0
staszko032 18 oct. 2017 a las 16:40