54 votes

Les ressources d’essai avec ressources Java interceptent-elles des erreurs ou juste des exceptions?

J'ai quelques junit tests de créer des ressources qui devraient également être fermé.

Une façon de mettre en œuvre cette logique est à l'aide de l' @Before et @After approche.

Ce que j'ai fait était pour encapsuler la création, sous une classe utilitaire pour être réutilisé. Par exemple:

class UserCreatorTestUtil implements AutoClosable {
  User create() {...}
  void close() {...}
}

Le point est pour l'objet de fermer lui-même, plutôt que d'avoir à vous rappeler de le fermer en @After.

L'usage doit être:

@Test
void test() {
  try (UserCreatorTestUtil userCreatorTestUtil = new UserCreatorTestUtil()) {
    User user = userCreatorTestUtil.create();
    // Do some stuff regarding the user's phone
    Assert.assertEquals("123456789", user.getPhone());
  }
}

Le problème est que junit est affirmer mot-clé déclenche une Error - pas d' Exception.

Va l'essayer-avec-ressource "attraper" l' Error et d'appeler la méthode close?

* Ne pouvais pas trouver la réponse dans le try-with-resources de la documentation.

73voto

Thilo Points 108673

Cela ne fait rien catch . Mais finally ferme toutes les ressources.

finally blocs sont exécutés même lorsqu'une erreur est renvoyée .

37voto

Nicolas Filotto Points 32004

Le pseudo-code d'une base try-with-resources déclaration est (cf Java Language Specification §14.20.3.1):

final VariableModifiers_minus_final R Identifier = Expression;
Throwable #primaryExc = null;

try ResourceSpecification_tail
    Block
catch (Throwable #t) {
    #primaryExc = #t;
    throw #t;
} finally {
    if (Identifier != null) {
        if (#primaryExc != null) {
            try {
                Identifier.close();
            } catch (Throwable #suppressedExc) {
                #primaryExc.addSuppressed(#suppressedExc);
            }
        } else {
            Identifier.close();
        }
    }
}

Comme vous pouvez le voir il attrape Throwable pas Exception qui inclut Error , mais seulement pour obtenir le primaire exception afin d'ajouter comme étant supprimés exceptions les exceptions qui s'est produite lors de la fermeture de la ressources.

Vous pouvez également remarquer que vos ressources sont fermées en finally bloc qui signifie qu' ils seront fermés quoi qu'il arrive (sauf dans le cas d'un System.exit bien sûr, comme il se termine en cours d'exécution de la Machine Virtuelle Java), même dans le cas d'un Error ou toute sous-classe de Throwable est levée.

13voto

Andy Turner Points 13883

Les ressources de test ne prennent rien en elles-mêmes.

Cependant, vous pouvez attacher un bloc catch à la fin du bloc try-with-resources pour capturer tous les types de Throwable vous aimez:

 try (UserCreatorTestUtil userCreatorTestUtil = new UserCreatorTestUtil()) {
  // ... Whatever
} catch (RuntimeException e) {
  // Handle e.
} catch (Exception | Throwable t) {
  // Handle t.
}
 

8voto

Raman Sahasi Points 14959

L'idée derrière le try-with-resources est de s'assurer que les ressources doivent être fermés.

Le problème avec les classiques try-catch-finally des déclarations, c'est que supposons que votre try bloc de lève une exception; maintenant généralement vous allez traiter cette exception à l' finally bloc.

Supposons maintenant qu'une exception se produit dans le bloc finally. Dans un tel cas, l'exception levée par try catch est perdu et l'exception générée en finally bloc obtient propagée.

try {
    // use something that's using resource
    // e.g., streams
} catch(IOException e) {
   // handle 
} finally {
    stream.close();
    //if any exception occurs in the above line, than that exception
    //will be propagated and the original exception that occurred
    //in try block is lost.
}

En try-with-resources le close() méthode de la ressource sera automatiquement appelé, et si l' close() lance une exception, le reste de l' finally n'est pas atteint, et l'exception d'origine est perdue.

Contrairement à ceci:

try (InputStream inputStream= new FileInputStream("C://test.txt")){
    // ... use stream
} catch(IOException e) {
   // handle exception
}

dans l'extrait de code ci-dessus, l' close() méthode est automatiquement appelée et si c' close() méthode a également généré une exception, que cette exception sera automatiquement supprimée.

Voir aussi: Java Language Specification 14.20.3

4voto

GhostCat Points 83269

Idée fausse sur votre fin: essayer avec des ressources ne fait pas de piège .

Il fait une finale enfin, donc le genre de « problème » n'a pas d' importance.

Voir le JLS pour plus d'informations!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X