Question

Je suis en train d'écrire un test pour un morceau de code qui contient une erreur IOException que j'essaie de couvrir. L'essai / capture ressemble à ceci:

try {
    oos = new ObjectOutputStream(new FileOutputStream(cacheFileName));
} catch (IOException e) {
    LOGGER.error("Bad news!", e);
} finally {

La manière la plus simple semble faire que FileOutputStream lève une exception FileNotFoundException, mais peut-être que j'y vais à fond.

Quelqu'un a-t-il des conseils?

Était-ce utile?

La solution

De votre commentaire:

  

Oui, je suppose que la question devrait   vraiment ont été "Comment puis-je créer un   fichier qui n'existe pas sous Linux   et Windows? " Sur les fenêtres, je peux utiliser   "nouveau fichier (" X: / ")", où X: est un lecteur   lettre qui n'existe pas. Sur Linux,   cela ne fonctionne pas parce que c'est un   nom de fichier valide.

Regardez java.io.File.createTempFile. Utilisez-le pour créer le fichier, puis supprimez-le.

Passez probablement quelque chose comme:

File tempFile;

tempFile = createTempFile(getClass().getName(), 
                          Long.toString(System.currentTimeMillis());
tempFile.delete();

Cela devrait vous donner un nom unique, d’une manière indépendante de la plate-forme, que vous pouvez utiliser en toute sécurité sans crainte (réelle) de son existence.

Autres conseils

Vous pouvez définir cacheFileName sur un nom non valide ou sur un nom qui n'existe pas.

Tout test comporte deux parties: le réaliser et mesurer le résultat correct.

Injection de défaut

La réponse la plus simple est celle qui a déjà été mentionnée, qui consiste à définir cacheFileName sur un fichier qui n'existera jamais. C’est probablement la réponse la plus pratique dans cette situation.

Toutefois, pour provoquer une condition arbitraire telle qu'une IOException , vous souhaitez réellement Injection de défaut . Cela force les fautes dans votre code sans vous obliger à instrumenter votre code source. Voici quelques méthodes pour cela:

  • Objets simulés : vous pouvez utiliser une méthode d'usine pour créer un ObjectOutputStream ou un FileOutputStream . Dans le code de test, l’implémentation lançait une IOException lorsque vous le souhaitiez, et dans le code de production, elle ne modifiait pas le comportement normal.
  • Injection de dépendance Pour placer votre objet fantaisie au bon endroit, vous pouvez utiliser un cadre tel que Spring ou Couture pour " injecter " l'objet approprié dans la classe qui fait le travail. Vous pouvez constater que ces frameworks ont même une priorité pour les objets à injecter, ce qui vous permet de remplacer les objets de production par des objets de test lors des tests unitaires.
  • Programmation orientée aspect Au lieu de modifier la structure de votre code, vous pouvez utiliser AOP pour injecter la faute au bon endroit. Par exemple, en utilisant AspectJ , vous pouvez définir un Pointcut à partir duquel vous voulez que l’exception soit levée et que le Advice lève l’exception souhaitée.

Il existe d’autres réponses à l’injection de faute sous Java; Par exemple, un produit appelé AProbe a été un pionnier de ce que l'on pourrait appeler il y a longtemps AOP en C, et ils ont également avoir un produit Java.

Validation

Obtenir l’exception levée est un bon début, mais vous devez également valider le résultat escompté. En supposant que l'exemple de code que vous avez là est correct, vous voulez valider que vous avez enregistré cette exception. Quelqu'un ci-dessus a mentionné l'utilisation d'un objet fantaisie pour votre enregistreur, ce qui est une option viable. Vous pouvez également utiliser AOP ici pour intercepter l'appel de l'enregistreur.

Je suppose que l'enregistreur est log4j ; pour résoudre un problème similaire, j’ai mis en place mon propre appender log4j qui capture la sortie log4j: j’ai capturé uniquement les balises ERROR et FATAL , qui sont susceptibles d’être les messages de journalisation intéressants un cas. L'appender est référencé dans log4j.xml et est activé pendant l'exécution du test pour capturer la sortie du journal des erreurs. Il s'agit essentiellement d'un objet fictif, mais je n'ai pas eu à restructurer tout mon code ayant reçu un Enregistreur de log4j.

  

J'écris un test pour un morceau de code   qui a une capture IOException dedans   que j'essaie de couvrir.

Je ne suis pas tout à fait sûr de comprendre votre objectif, mais si vous souhaitez vérifier si l'exception est levée, vous pouvez indiquer le test auquel vous vous attendez:

@Test(expected=IOException.class)

Votre test échouera alors si l'exception n'est pas levée et réussit s'il est levé (comme si le fichier cacheFileName n'existait pas).

Une exception FileNotFoundException déclencherait évidemment la capture. Le javadoc indique les cas où il sera lancé.

Vous devriez également considérer que le constructeur ObjectOutputStream peut émettre une exception IOException et qu'il peut donc vouloir couvrir ce cas dans vos tests.

Deux manières simples sont de définir cacheFileName sur un fichier inexistant ou de définir le fichier spécifié sur un accès en lecture seule.

-John

Le code étant en cours d’écriture, vous pouvez essayer de simuler l’appel error () sur l’objet LOGGER et vérifier s’il est appelé lorsque vous attendez une exception IOException.

Votre désir de tester a peut-être révélé un problème fondamental avec le code tel qu'il est écrit. Une erreur se produit, mais il n'existe aucune valeur booléenne ou indicateur (définissez le nom de fichier sur un modèle spécial) fournissant d'autres sections de code permettant de déterminer si l'écriture dans le fichier a réussi. Si cela est contenu dans une fonction, vous pourriez peut-être retourner un booléen ou définir une variable de niveau objet.

cacheFileName = "thisFileShouldNeverExistAndIfItDoesYouAreScrewingUpMyTests";

Bien sûr, vous pouvez prendre des mesures et passer à travers des étapes pour vous assurer par programme que le nom du fichier n’existera jamais, ou vous pouvez utiliser une chaîne qui n’existera jamais dans 99,99999% des cas.

J'espère que c'est ce que vous vouliez dire.

if(new File(cachedFile).exists()) {
    oos = new ObjectOutputStream(new FileOutputStream(cacheFileName));
    //do your code here
} else {
    throw new FileNotFoundException("File doesn't exist!");
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top