Zum Inhalt springen

Parametrisierte jUnit 5-Tests mit eigenen Datentypen/Klassen-Objekten als Test-Parameter


DITTY

Empfohlene Beiträge

Hallo Zusammen,

ich bin derzeit dabei mich in jUnit 5 einzuarbeiten (mit Migrationsprojekten von jUnit 4 zu jUnit 5).
Leider stoße ich derzeit an ein paar Grenzen meiner Kenntnisse. Konkret geht es um die nachfolgend genannten Dinge.
Für Lösungen verwende ich u.a. diese Seite hier: https://howtoprogram.xyz/2016/10/28/junit-5-parameter-resolution-example/
(natürlich auch noch andere: z.B. https://junit.org/junit5/docs/current/user-guide/)

Ich möchte gerne einfache Non-Parameterized- als auch Parameterized jUnit 5-Tests ausführen lassen, wo ich als Testfunktionsparameter jedoch keine Standarddatentypen (primitive, String, ENUMs, etc.) an die Testinstanzen übergebe, sondern Objekte eines eigenen Datentyps (ClientDescription).

ClientDescription ist wie folgt definiert:

package ISHQA.StdLibCore;

public class ClientDescription
{
    public String ...;
    public String ...;
    public String ...;
    public String ...;
    public String ...;
    public String ...;
    public String ...;
    
    public ClientDescription()
    {

    }  
    
    public ClientDescription(String, String, String, String, String, String, String)
    {
        ...
    }
}

Hierzu habe ich für meine Klasse einen ParameterResolver (Parameter Resolution by type) geschrieben:

package ISHQA.StdLibCore.jUnit;

import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.ParameterContext;
import org.junit.jupiter.api.extension.ParameterResolutionException;
import org.junit.jupiter.api.extension.ParameterResolver;

import ISHQA.StdLibCore.ClientDescription;

public class ClientDescriptionParameterResolver implements ParameterResolver
{
    @Override
    public Object resolveParameter(ParameterContext parameterContext,
                                   ExtensionContext extensionContext) throws ParameterResolutionException
    {
        return new ClientDescription();
    }
   
    @Override
    public boolean supportsParameter(ParameterContext parameterContext,
                                     ExtensionContext extensionContext) throws ParameterResolutionException
    {
        return (parameterContext.getParameter().getType() == ClientDescription.class);
    }
}

Damit funktioniert hier schonmal dieser nicht parametrisierte Test (test02(ClientDescription)):

TestClass01.java:
==================================================================

package Main.Demo;

import ISHQA.StdLibCore.ClientDescription;
import ISHQA.StdLibCore.jUnit.*;

@RunWith(JUnitPlatform.class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@ExtendWith(ClientDescriptionParameterResolver.class)
@DisplayName("Test cases")
public class TestClass01
{
    //...
    
    @Test
    public void test02(ClientDescription client)
    {
        //...client...
    }

    //...
}

Nun bräuchte ich Rat / Hilfe beim Implementieren für folgende weiteren Dinge:

1.) Ich möchte das obige Beispiel gerne auf die gleiche Weise für parametrisierte Tests ausführen lassen, analog zum Beispiel für Strings:

TestClass01.java:
==================================================================

//...

@DisplayName("Test Case 01")
@ParameterizedTest(name = "{index} with [{arguments}]")
@ValueSource(strings = { "'EAH','Prod','LIVE','DE','de'" })
public void test01(String testData) throws Exception
{    
    //...using testData...
}

//...

Ich möchte gerne bei @ValueSource Objekte meines eigenen Datentyps angeben wollen, die übergeben werden sollen.
Nur wie ist die Notation hierfür? Strings und Zahlen sind mir klar (siehe Beispiel), aber wie bei Klassenobjekten???
Und muss die ClientDescriptionParameterResolver-Klasse dazu noch angepasst werden?

2.) Ich möchte gerne den ClientDescriptionParameterResolver dahingehend anpassen, dass er mit beiden Konstruktoren von ClientDescription zurecht kommt, also wahlweise beide ausführen kann.
Aktuell führt der ClientDescriptionParameterResolver nur den Standardkonstruktor von "ClientDescription()" aus, sodass jeder Testrun stets ein neu instantiiertes Objekt erhält.
Im Hintergrund habe ich eine hardcodierte "Datenbank" mit mehreren Objekten vom Typ ClientDescription, die ich gerne für einzelne Testruns übergeben möchte.
Muss ich hierfür den ClientDescriptionParameterResolver entsprechend abändern?

3.) Nach der Dokumentation kann man Parameter nach Name, Typ (wie oben schon implementiert), Annotation oder Kombinationen von diesen resolven.

Analog zur Implementierung "Parameter Resolution by type" habe ich noch eine für "Parameter Resolution by annotation" versucht umzusetzen:

ClientDescriptionAnnotationParameterResolver.java:
==================================================================

package ISHQA.StdLibCore.jUnit;

import java.lang.annotation.Annotation;

import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.ParameterContext;
import org.junit.jupiter.api.extension.ParameterResolutionException;
import org.junit.jupiter.api.extension.ParameterResolver;
import org.junit.platform.commons.util.ReflectionUtils;

public class ClientDescriptionAnnotationParameterResolver implements ParameterResolver
{
    @Override
    public Object resolveParameter(ParameterContext parameterContext,
                                   ExtensionContext extensionContext) throws ParameterResolutionException
    {
        return ReflectionUtils.newInstance(parameterContext.getParameter().getType());
    }
   
    @Override
    public boolean supportsParameter(ParameterContext parameterContext,
                                     ExtensionContext extensionContext) throws ParameterResolutionException
    {
        return parameterContext.getParameter().isAnnotationPresent(ClientDescriptionParam.class);
    }
}

ClientDescriptionParam.java:
==================================================================

package ISHQA.StdLibCore.jUnit;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ClientDescriptionParam
{
}

, sodass Folgendes dann möglich wird:

TestClass02.java:
==================================================================

package Main.Demo;

import ISHQA.StdLibCore.ClientDescription;
import ISHQA.StdLibCore.jUnit.*;

@RunWith(JUnitPlatform.class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@ExtendWith(ClientDescriptionAnnotationParameterResolver.class)
@DisplayName("Test cases")
public class TestClass02
{
    //...

    @Test
    public void test03(@ClientDescriptionParam ClientDescription client)
    {
        //...
    }    
    
    //...
}

oder bzgl. der Parameter in Kombination alle Möglichkeiten zusammen:
TestClass03.java:
==================================================================

package Main.Demo;

import ISHQA.StdLibCore.ClientDescription;
import ISHQA.StdLibCore.jUnit.*;

@RunWith(JUnitPlatform.class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@ExtendWith(ClientDescriptionParameterResolver.class)
@DisplayName("Test cases")
public class TestClass03
{
    //...
    
    @Test
    public void test02(ClientDescription client)
    {
        
    }
    
    @Test
    public void test03(@ClientDescriptionParam ClientDescription client)
    {
        
    }    
    
    @ClientDescriptionParam
    @Test
    public void test04(ClientDescription client)
    {
        
    }    
    
    @ClientDescriptionParam
    @Test
    public void test05(@ClientDescriptionParam ClientDescription client)
    {
       
    }  

    //...
}

Auch hier analog zu 1.) und 2.) die Frage, was ich wo und wie anpassen muss, damit a.) meine eigene Annotation "@ClientDescriptionParam" auch bei @ParameterizedTest-Tests verwendbar wird, nicht nur bei @Test-Tests.

Habt schonmal besten Dank im Voraus für Eure Hilfen.

VG

DITTY

Bearbeitet von DITTY
Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...