Domanda

Quello che ho adesso

Ho un'istanza singleton di terze parti su cui fa affidamento la mia classe sotto test e che singleton sta usando System.getenv (String) nel suo costruttore. È possibile deridere questa chiamata?

Ho provato questo

Esempio di JMockIt

    new Expectations()
    {

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

Ma mi dà un EXCEPTION_ACCESS_VIOLATION e si blocca la JVM.

Esiste un altro modo per impostare una variabile di ambiente di sistema per un unit test?

È stato utile?

Soluzione

In questo caso è necessario utilizzare il derisione parziale in modo che JMockit non ridefinisca tutto nella classe System. Il seguente test verrà superato:

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

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

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

Presto implementerò un miglioramento in modo che problemi come questo non si verifichino quando deridono le classi JRE. Dovrebbe essere disponibile nella versione 0.992 o 0.993.

Altri suggerimenti

PowerMock cuciture per essere in grado di deridere le classi di sistema.

L'altra tua opzione (supponendo che tu non stia testando l'API di terze parti) è quella di creare una facciata l'API di terze parti che ha un'interfaccia simpatica e facile da deridere e fa in modo che le tue classi di test usino questa cosa piuttosto che la cosa reale.

Oh, JMock supporta anche questo:     pacchetto playtest;

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";
  }
 }

}

Non è possibile modificare l'ambiente ma è possibile modificarne l'accesso: è sufficiente racchiudere la chiamata in System.getenv () in un metodo o in una classe helper e quindi deridere quello.

[EDIT] Ora il tuo problema è come cambiare il codice della tua libreria di terze parti. La soluzione qui è usare un decompilatore Java e correggere la classe. Se lo desideri, puoi anche inviare una richiesta di funzione. Aggiungi quella nuova classe alla tua suite di test. Questo dovrebbe far sì che il tuo IDE trovi la classe per i test.

Poiché il codice di test non viene messo in produzione, è possibile eseguire i test e il codice di produzione utilizzerà la libreria originale.

Qualche tempo fa volevo test System.exit , e ho trovato una soluzione utilizzando un SecurityManager personalizzato . È possibile verificare che la chiamata sia in corso e l'argomento della chiamata, ma utilizzando questo metodo non è possibile deridere il valore restituito della chiamata.

Un aggiornamento sulla risposta di @ Rogério.

Nel mio caso con JMockit 1.25 ho dovuto farlo utilizzando l'API MockUp:

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

    assertEquals(".", System.getenv("envVar"));
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top