Testing JUnit5: try ... catch arbeitet nicht sauber

TM69

Bekanntes Mitglied
Ich habe eine Spring - Funktion:
Java:
    public FieldDescription createFieldDescription(User creator, FieldDescription fieldDescription) throws ResourceNotFoundException {
        
        if (creator == null)
            throw new IllegalArgumentException("The creator must not be zero");
        
        if (fieldDescription == null)
            throw new IllegalArgumentException("The adding field description must not be zero");
        
        userRepository.findById(creator.getId())
            .orElseThrow(() -> new ResourceNotFoundException("Creator not found with the id :: " + creator.getId()));
        
        fieldDescription.setId(sequenceGeneratorService.generateSequence(FieldDescription.SEQUENCE_NAME));
        fieldDescription.setCreatedBy(creator);
        fieldDescription.setCreatedAt(LocalDateTime.now());
        
        return fieldDescriptionRepository.save(fieldDescription);
    }

und eine zugehörige JUnit5 Test-Funktion
Code:
    @Test
    void testCreateWiFieldDescriptionthWithNotExistsUserShouldThrowResourceNotFoundException() throws ResourceNotFoundException {
        // create a basic user
        String firstname = "firstname";
        String lastname = "lastname";
        String email = "email@email.com";
        String password = "password";
        
        User user = new User(
                firstname,                // password
                lastname,                 // lastname
                email,                     // email
                password                // password
                );
        boolean exception = false;
        
        try {
            userService.createUser(null, user);
        } catch (ResourceNotFoundException e) {
            exception = true;
            e.printStackTrace();
        }

        assertFalse(exception, "testCreateWiFieldDescriptionthWithNotExistsUserShouldThrowResourceNotFoundException(): Couldnt create user");
        assertNotNull(user);
        
        // create basic field description
        user.setId(999999);                   // set user to an illagel index
        
        String name = "aFieldname";
        EFieldType fieldType = EFieldType.TEXT;
        String options = "options";
        
        FieldDescription fieldDescription = new FieldDescription(name, fieldType, options);
        
        exception = false;
        
        try {
            fieldService.createFieldDescription(user, fieldDescription);
        } catch (ResourceNotFoundException e) {
            exception = true;
            e.printStackTrace();
        }
        
        assertTrue(exception, "testCreateWiFieldDescriptionthWithNotExistsUserShouldThrowResourceNotFoundException(): FieldDescription could be create");

        // clean up
        userService.removeUser(user.getId());
    }

Ich sehe das die zu testende Funktion wirklich eine ResourceNotFoundException wirft, wenn ein nicht existende User ID übergeben wurde. Oder anders gesagt der Abschnitt
Code:
    userRepository.findById(creator.getId())

            .orElseThrow(() -> new ResourceNotFoundException("Creator not found with the id :: " + creator.getId()));

arbeitet sauber, aber in der Test-Funktion an der Stelle
Code:
        try {
            fieldService.createFieldDescription(user, fieldDescription);
        } catch (ResourceNotFoundException e) {
            exception = true;
            e.printStackTrace();
        }

scheint es fast so als würde catch nicht anspringen.
Denn
Code:
        assertTrue(exception, "testCreateFieldDescriptionthWithNotExistsUserShouldThrowResourceNotFoundException(): FieldDescription could be create");
wird mit true quitiert und nicht wie eigentlich gedacht als false.
 

httpdigest

Top Contributor
in der Test-Funktion an der Stelle
Code:
        try {
            fieldService.createFieldDescription(user, fieldDescription);
        } catch (ResourceNotFoundException e) {
            exception = true;
            e.printStackTrace();
        }

scheint es fast so als würde catch nicht anspringen.
Denn
Code:
        assertTrue(exception, "testCreateFieldDescriptionthWithNotExistsUserShouldThrowResourceNotFoundException(): FieldDescription could be create");
wird mit true quitiert und nicht wie eigentlich gedacht als false.
Diese Angaben sind widersprüchlich. Du schreibst, dass es so scheint, als würde der catch-Block nicht ausgeführt werden, aber anschließend schreibst du, dass assertTrue(exception, ...) ja ohne AssertionError durchläuft. Also wurde doch der catch-Block durchlaufen, weil nur dann auch die boolean Variable exception auch auf true gesetzt wird. Also: Es hat alles ganz genau so funktioniert, wie von dir erwartet.

Nichtsdestotrotz ist diese Art der Prüfung und die Verwendung von boolean Variablen hierfür nicht sinnvoll. Siehe Nachricht von @thecain .
 

KonradN

Super-Moderator
Mitarbeiter
Wenn eine Exception nicht gefangen wird, ist der Test an der Stelle mit der Exception automatisch fehlgeschlagen.
Daher ist sowas nicht explizit zu testen.
 

TM69

Bekanntes Mitglied
Wenn eine Exception nicht gefangen wird, ist der Test an der Stelle mit der Exception automatisch fehlgeschlagen.
Daher ist sowas nicht explizit zu testen.
Das hab ich mir schon gedacht, allerdings frage ich mich wie ich z.B. folgenden Test anhand der von theCain geschriebenen Antworten "besser" schreiben könnte.
Java:
        // initialize: create a basic user
        String firstname = "firstname";
        String lastname = "lastname";
        String email = "email@email.com";
        String password = "password";
        
        User user = new User(
                firstname,                // password
                lastname,                 // lastname
                email,                     // email
                password                // password
                );
        
        ResourceNotFoundException thrown = Assertions.assertThrows(FieldDescription.class, () -> {
               //Code under test
      });

      Assertions.assertEquals("some message", exception.getMessage());
      
        boolean exception = false;
        
        try {
            userService.createUser(null, user);
        } catch (ResourceNotFoundException e) {
            exception = true;
            e.printStackTrace();
        }
        
        assertFalse(exception, "testCreateWiFieldDescriptionthMinimalistValidData(): Couldnt create user");
        
        // test: create basic field description
        String name = "aFieldname";
        EFieldType fieldType = EFieldType.TEXT;
        String options = "options";
        
        FieldDescription fieldDescription = new FieldDescription(name, fieldType, options);
        
        exception = false;
        
        try {
            fieldService.createFieldDescription(user, fieldDescription);
        } catch (ResourceNotFoundException e) {
            exception = true;
            e.printStackTrace();
        }
        
        assertFalse(exception, "testCreateFieldDescriptionthMinimalistValidData(): Couldnt create FieldDescription");
        
        Optional<FieldDescription> foundFieldDescription = fieldService.findFieldDescriptionById(fieldDescription.getId());
        
        assertTrue( foundFieldDescription.isPresent(), "testCreateFieldDescriptionthMinimalistValidData(): Not found FieldDescription" );
        
        assertEquals(name, foundFieldDescription.get().getName(), "testCreateWiFieldDescriptionthMinimalistValidData(): Name of FieldDescription not identical");
        assertEquals(fieldType, foundFieldDescription.get().getFieldType(), "testCreateWiFieldDescriptionthMinimalistValidData(): FieldType of FieldDescription not identical");
        assertEquals(options, foundFieldDescription.get().getOptions(), "testCreateWiFieldDescriptionthMinimalistValidData(): Options of FieldDescription not identical");
        
        // clean up
        fieldService.removeFieldDescription(fieldDescription.getId());
        userService.removeUser(user.getId());
 

httpdigest

Top Contributor
Wann immer du sowas schreiben wolltest (Exception soll nicht fliegen):
Java:
exception = false;
try {
    fieldService.createFieldDescription(user, fieldDescription);
} catch (ResourceNotFoundException e) {
    exception = true;
    e.printStackTrace();
}
assertFalse(exception, "testCreateFieldDescriptionthMinimalistValidData(): Couldnt create FieldDescription");
schreibst du stattdessen jetzt einfach:
Java:
fieldService.createFieldDescription(user, fieldDescription);

Und statt (Exception soll fliegen):
Java:
exception = false;
try {
    fieldService.createFieldDescription(user, fieldDescription);
} catch (ResourceNotFoundException e) {
    exception = true;
    e.printStackTrace();
}
assertTrue(exception, "testCreateWiFieldDescriptionthWithNotExistsUserShouldThrowResourceNotFoundException(): FieldDescription could be create");
schreibst du jetzt halt:
Java:
assertThrows(ResourceNotFoundException.class, () -> fieldService.createFieldDescription(user, fieldDescription));
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
J Junit start surefire for manual testing Allgemeine Java-Themen 1
S Unit Testing mit JMock Allgemeine Java-Themen 11
M IndexOutOfBoundsException / Try-Catch Allgemeine Java-Themen 9
K Zweifacher Try-Catch Allgemeine Java-Themen 6
ralfb1105 LogManager logger schreibt nicht in Catch() Zweig Allgemeine Java-Themen 2
C try-catch Block Verständnisfrage Allgemeine Java-Themen 14
F Try/catch über ganze Klasse Allgemeine Java-Themen 9
C Unendlich Wiederholungsfehler bei try catch - Block Allgemeine Java-Themen 3
H try catch Allgemeine Java-Themen 4
V Designfrage: try-catch-throws Allgemeine Java-Themen 11
E Immer nur der Catch-Zweig Allgemeine Java-Themen 3
N String aus Try/Catch-Block übernehen Allgemeine Java-Themen 14
B Execption auf Oberfläche werfen, try-catch-Block Allgemeine Java-Themen 6
T class.newinstance + try/catch-konstruktor Allgemeine Java-Themen 6
R return in try-catch-Blöcken Allgemeine Java-Themen 6
I Exceptions - weder catch- noch finally-Klausel funktioniert Allgemeine Java-Themen 12
F try und catch Blöcke Allgemeine Java-Themen 3
Final_Striker Exceptionhandling: Richtige Verwendung des Try/Catch Blocks Allgemeine Java-Themen 14
M Try-Catch: wie wird Variable bei Exception initialisiert? Allgemeine Java-Themen 8
P Methodenaufruf von catch Allgemeine Java-Themen 2
S native methoden in try / catch ? Allgemeine Java-Themen 3
V Was tun mit "nötigen" Catch-Blöcken? Allgemeine Java-Themen 3
V Try-Catch und Code der folgt? Allgemeine Java-Themen 3
B Try/Catch in While-Schleife mit Scanner - Hilfe! Allgemeine Java-Themen 3
E try/catch Block um ganzes Programm Allgemeine Java-Themen 10
T rießiger try - catch - Block Allgemeine Java-Themen 13
M try-catch (Wie erzwing ich die catch-Anweisung)? Allgemeine Java-Themen 13
L Try ... Catch Allgemeine Java-Themen 3

Ähnliche Java Themen

Neue Themen


Oben