Question

Ce que j'ai en ce moment

J'ai une instance singleton tierce sur laquelle ma classe testée s'appuie et que singleton utilise System.getenv (String) dans son constructeur. Est-il possible de se moquer de cet appel?

j'ai essayé ceci

Exemple JMockIt

    new Expectations()
    {

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

Mais cela me donne un EXCEPTION_ACCESS_VIOLATION et provoque le blocage de la machine virtuelle.

Existe-t-il un autre moyen de définir une variable d'environnement système pour un test unitaire?

Était-ce utile?

La solution

Dans ce cas, vous devez utiliser une moquage partiel afin que JMockit ne redéfinisse pas tout dans la classe System. Le test suivant réussira:

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

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

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

Je vais bientôt implémenter une amélioration afin que de tels problèmes ne se produisent pas lorsque vous vous moquez des classes JRE. Il devrait être disponible dans les versions 0.992 ou 0.993.

Autres conseils

PowerMock permet de simuler des classes système.

Votre autre option (en supposant que vous n'êtes pas en train de tester l'API tierce) consiste à créer une façade. l'API tierce qui possède une interface agréable et facile à utiliser et que vos classes de test utilisent plutôt que la réalité.

Oh, JMockIt supporte ça aussi:     package 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";
  }
 }

}

Vous ne pouvez pas modifier l'environnement mais vous pouvez en modifier l'accès: insérez simplement l'appel dans System.getenv () dans une méthode ou une classe auxiliaire, puis modifiez-le.

[EDIT] Maintenant, votre problème est de savoir comment changer le code de votre bibliothèque tierce. La solution ici consiste à utiliser un décompilateur Java et à corriger la classe. Si vous le souhaitez, vous pouvez également envoyer une demande de fonctionnalité. Ajoutez cette nouvelle classe à votre suite de tests. Cela devrait permettre à votre IDE de trouver la classe pour les tests.

Le code de test n'étant pas mis en production, vous pouvez exécuter vos tests et le code de production utilisera la bibliothèque d'origine.

Il ya quelque temps, je souhaitais tester System.exit , et a trouvé une solution en utilisant un SecurityManager personnalisé . Vous pouvez vérifier que l'appel est en cours et l'argument de l'appel, mais en utilisant cette méthode, vous ne pouvez pas vous moquer de la valeur de retour de l'appel.

Une mise à jour de la réponse @ Rog & # 233; rio.

Dans mon cas avec JMockit 1.25, je devais le faire à l'aide de l'API MockUp:

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

    assertEquals(".", System.getenv("envVar"));
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top