Supponendo che la classe è qualcosa di simile:
class ClassToTest {
public void doSomething() {
String sessionId = RequestContextHolder.currentRequestAttributes().getSessionId();
// Do something with sessionId
}
}
Se non si ha la capacità di cambiare la classe che utilizza RequestContextHolder
, allora si potrebbe sostituire la classe RequestContextHolder
nel codice di prova. I.e. crei una classe con lo stesso nome, nello stesso pacchetto, e assicurati che venga caricata prima della classe Spring effettiva.
package org.springframework.web.context.request;
public class RequestContextHolder {
static RequestAttributes currentRequestAttributes() {
return new MyRequestAttributes();
}
static class MyRequestAttributes implements RequestAttributes {
public String getSessionId() {
return "stub session id";
}
// Stub out the other methods.
}
}
Ora, quando i test eseguiti, prenderanno in mano la vostra classe RequestContextHolder
e l'uso che di preferenza a primavera uno (assumendo che il percorso di classe è predisposto per questo accada). Questo non è un modo particolare per eseguire i test, ma potrebbe essere necessario se non è possibile modificare la classe che si sta testando.
In alternativa, è possibile nascondere il recupero dell'ID di sessione dietro un'astrazione. Per esempio introdurre un'interfaccia:
public interface SessionIdAccessor {
public String getSessionId();
}
Creare un'implementazione:
public class RequestContextHolderSessionIdAccessor implements SessionIdAccessor {
public String getSessionId() {
return RequestContextHolder.currentRequestAttributes().getSessionId();
}
}
e utilizzare l'astrazione nella classe:
class ClassToTest {
SessionIdAccessor sessionIdAccessor;
public ClassToTest(SessionIdAccessor sessionIdAccessor) {
this.sessionIdAccessor = sessionIdAccessor;
}
public void doSomething() {
String sessionId = sessionIdAccessor.getSessionId();
// Do something with sessionId
}
}
Quindi è possibile fornire un'implementazione fittizia per i test:
public class DummySessionIdAccessor implements SessionIdAccessor {
public String getSessionId() {
return "dummy session id";
}
}
Questo tipo di cose mette in evidenza una consueta best practice per nascondere determinati dettagli ambientali dietro alle astrazioni, in modo che tu possa scambiarli se il tuo ambiente cambia. Ciò vale anche per rendere i test meno fragili sostituendo le implementazioni fittizie con quelle "reali".
Grazie @ nicholas.hauschild. Soluzione perfetta e pulita! – satoshi
@nicholas, grazie per la soluzione rapida, ha funzionato per me, grazie ancora una volta – Bravo