Servlet-Filter in Java testen: Wie kann man Änderungen im Context vor dem Aufruf von clear() im finally-Block prüfen

DrPils

Bekanntes Mitglied
Hi

Damit in meiner Rest api die timezone konfigurierbar ist, habe ich eine Filter erstellt, der den timezone paramerter entgegen nimmt und diesen dem context übergibt.
Dafür würde ich gerne einen Unit test schreiben. Jedoch setze ich den Context im finally block wieder zurück, was dazu führt, dass ich den Inhalt des contextes nach aufruf der doFilter() nicht mehr überprüfen kann. Die Methode im TimezoneContext kann ich auch nicht spyen, da diese statisch ist.
Kann ich hier irgendwas sinnvolles tun um einen Unit Test zu schreiben?

Java:
@Component
public class TimeZoneFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String timeZoneParam = httpRequest.getParameter("timezone");

        TimeZoneContext.setTimeZone(ZoneId.of(Objects.requireNonNullElse(timeZoneParam, "UTC")));

        try {
            chain.doFilter(request, response);
        } finally {
            TimeZoneContext.clear();
        }
    }
}

Code:
public class TimeZoneContext {
    private static final ThreadLocal<ZoneId> timeZoneHolder = new ThreadLocal<>();

    public static void setTimeZone(ZoneId zoneId) {
        timeZoneHolder.set(zoneId);
    }

    public static ZoneId getTimeZone() {
        return timeZoneHolder.get() != null ? timeZoneHolder.get() : ZoneId.of("UTC");
    }

    public static void clear() {
        timeZoneHolder.remove();
    }
}

Java:
class TimeZoneContextTest {

    @AfterEach
    void tearDown() {
        TimeZoneContext.clear();
    }

    @Test
    void should_return_default_timezone_utc() {
        ZoneId result = TimeZoneContext.getTimeZone();

        assertEquals(ZoneId.of("UTC"), result);
    }

    @Test
    void should_set_timezone() {
        TimeZoneContext.setTimeZone(ZoneId.of("Europe/Berlin"));

        ZoneId timeZone = TimeZoneContext.getTimeZone();

        assertEquals(ZoneId.of("Europe/Berlin"), timeZone); //TimeZoneContext.clear() wurde im finally block aufgerufen -> context ist leer und returnt "UTC"
    }

}
 

LimDul

Top Contributor
Ich verstehe das Problem nicht ganz - zumindest bezogen auf den Code:
Java:
    @Test
    void should_set_timezone() {
        TimeZoneContext.setTimeZone(ZoneId.of("Europe/Berlin"));

        ZoneId timeZone = TimeZoneContext.getTimeZone();

        assertEquals(ZoneId.of("Europe/Berlin"), timeZone); //TimeZoneContext.clear() wurde im finally block aufgerufen -> context ist leer und returnt "UTC"
    }
Wo wird da ein finally Block aufgerufen? Du testet ja nur die Klasse TimeZoneContext - da gibt es keinen finally Block.
 

LimDul

Top Contributor
Sofern es um den Test der FilterChain geht - ja, da ist das ein Problem. Neben PowerMock (was ich noch nie genutzt habe) wäre eine Lösung einfach die statischen Aufrufe aus der FilterChain rauszuwerfen, und eine TimeZoneContextFassade als Component zu injecten, die nichts anders macht als an den TimeZoneContext durchzureichen. Dann kannst du die Fassade im Test mocken/mit einer Test-Implementierung austauschen
 

DrPils

Bekanntes Mitglied
Ich verstehe das Problem nicht ganz - zumindest bezogen auf den Code:
Java:
    @Test
    void should_set_timezone() {
        TimeZoneContext.setTimeZone(ZoneId.of("Europe/Berlin"));

        ZoneId timeZone = TimeZoneContext.getTimeZone();

        assertEquals(ZoneId.of("Europe/Berlin"), timeZone); //TimeZoneContext.clear() wurde im finally block aufgerufen -> context ist leer und returnt "UTC"
    }
Wo wird da ein finally Block aufgerufen? Du testet ja nur die Klasse TimeZoneContext - da gibt es keinen finally Block.
Ja vollkommen richtig, habe den falschen Test kopiert
 

DrPils

Bekanntes Mitglied
Sofern es um den Test der FilterChain geht - ja, da ist das ein Problem. Neben PowerMock (was ich noch nie genutzt habe) wäre eine Lösung einfach die statischen Aufrufe aus der FilterChain rauszuwerfen, und eine TimeZoneContextFassade als Component zu injecten, die nichts anders macht als an den TimeZoneContext durchzureichen. Dann kannst du die Fassade im Test mocken/mit einer Test-Implementierung austauschen
OK danke. Auf Mock Frameworks wollte ich diesesmal verzichten, da die immer die Tests aufblähen, ich schreibe statt dessen eigene Mock Implementierungen. Werde dann mal die lösung mit der Fassade probieren.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
H Konfigurierbarer Filter für OSGi service-Referenz in blueprint Frameworks - Spring, Play, Blade, Vaadin & Co 0
OnDemand JTE Java-Template-Engine Frameworks - Spring, Play, Blade, Vaadin & Co 2
Jose05 Java Anwendung, über den Browser steuern Frameworks - Spring, Play, Blade, Vaadin & Co 1
S java springboot HTML Produktstruktur Frameworks - Spring, Play, Blade, Vaadin & Co 1
G Java springboot Item mit ItemInstance verbinden Frameworks - Spring, Play, Blade, Vaadin & Co 2
thor_norsk Javac nicht vorhanden in Java-17-openjdk-amd64 Frameworks - Spring, Play, Blade, Vaadin & Co 8
padde479 Cannot invoke "java.util.Map.containsKey(Object)" because "requestMap" is null Frameworks - Spring, Play, Blade, Vaadin & Co 2
OnDemand Vaadin Pro & TypScript vs Plain Java Frameworks - Spring, Play, Blade, Vaadin & Co 4
S Java Web App oder PHP Frameworks - Spring, Play, Blade, Vaadin & Co 10
Zrebna SpringBoot-Project: java.sql.SQLSyntaxErrorException: Access denied for user 'gap3'@'%' to database '3306/gap3' Frameworks - Spring, Play, Blade, Vaadin & Co 3
L Hilfe beim Erstellen einer Java Web Anwendung gesucht Frameworks - Spring, Play, Blade, Vaadin & Co 5
8u3631984 required a bean of type 'java.lang.String' that could not be found. Frameworks - Spring, Play, Blade, Vaadin & Co 8
M Java Spring Security Frameworks - Spring, Play, Blade, Vaadin & Co 5
OnDemand Webfrontend mit Java Backend Frameworks - Spring, Play, Blade, Vaadin & Co 26
F Server-Java-Spring Websockets Frameworks - Spring, Play, Blade, Vaadin & Co 6
L Controller Spring Boot mit Java Frameworks - Spring, Play, Blade, Vaadin & Co 20
J Spring Boot Thymleaf mit Java.Optional Frameworks - Spring, Play, Blade, Vaadin & Co 0
B Java Spring Boot - POM-Problem Frameworks - Spring, Play, Blade, Vaadin & Co 8
H OAuth2 mit Spring boot und Java Frameworks - Spring, Play, Blade, Vaadin & Co 5
P Java EE vs. Spring Frameworks - Spring, Play, Blade, Vaadin & Co 2
K Spring Security für Java SE Frameworks - Spring, Play, Blade, Vaadin & Co 2
V Java (Eclipse) programmierung zum Springerproblem Frameworks - Spring, Play, Blade, Vaadin & Co 1
M Java for-Schleife überspringt eine Eingabe Frameworks - Spring, Play, Blade, Vaadin & Co 11
Java.getSkill() Gemeinsam Java Spring lernen Frameworks - Spring, Play, Blade, Vaadin & Co 17
S Senior-Softwareentwickler (m/w) Java / Spring im Raum Frankfurt Frameworks - Spring, Play, Blade, Vaadin & Co 0
MQue Meine Java Spring Appl Frameworks - Spring, Play, Blade, Vaadin & Co 0
W Java Applet aus der Taskleiste springt in Vordergrund Frameworks - Spring, Play, Blade, Vaadin & Co 3
S Java Applet:Thread.Timeout überspringt Teile des Codes Frameworks - Spring, Play, Blade, Vaadin & Co 2
S Integrations Test in Java mit Spring Frameworks - Spring, Play, Blade, Vaadin & Co 2
A Java Bean Validation und Spring Webflow Frameworks - Spring, Play, Blade, Vaadin & Co 0
Y java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener Frameworks - Spring, Play, Blade, Vaadin & Co 14
W java Spring mit db Frameworks - Spring, Play, Blade, Vaadin & Co 1
nrg Debugger springt immer in Java SE Code Frameworks - Spring, Play, Blade, Vaadin & Co 3
B Spring / Jpa / Hibernate -> java.lang.IllegalArgumentException: Unknown entity Frameworks - Spring, Play, Blade, Vaadin & Co 1
H java web anwendung auf spring 2.0 umstellen Frameworks - Spring, Play, Blade, Vaadin & Co 3

Ähnliche Java Themen


Oben