Ho un pattern ripetuto nel mio codice che non è facile da testare: classi che vengono eseguite periodicamente. Solo per semplificare le cose, diciamo, assumiamo qualcosa del tipo:
while( running ){
long millisToWait = scheduler.getMillisecondsUntilNextExecution();
Thread.sleep(millisToWait);
executeMyTask();
}
Dove Thread.sleep è un metodo statico che è difficile da modificare. Non importa se iniettare un orologio personalizzato nello scheduler perché la modifica dell'orologio non modificherà il tempo di sospensione. Penso che la soluzione potrebbe essere quella di creare una classe ThreadSleeper.
System.currentMillis -> replace by injected Clock.millis();
Thread.sleep(millisToWait) -> replace by injected ThreadSleeper.sleep(millisToWait)
Dove ThreadSleeper può essere qualcosa di simile;
import java.util.concurrent.Semaphore;
public abstract class ThreadSleeper {
public abstract void sleep(long millisecondsToSleep) throws InterruptedException;
public static SystemThreadSleeper systemThreadSleeper(){
return new SystemThreadSleeper();
}
public static ThreadSleeper testThreadSleeper(){
return new TestThreadSleeper();
}
public static final class TestThreadSleeper extends ThreadSleeper{
private Semaphore semaphore = new Semaphore(0);
private Long millisecondsToSleep = null;
//FIXME: make usable my multithread.
//TODO: add method simulateMillisecondsPasses.
@Override
public synchronized void sleep(long millisecondsToSleep) throws InterruptedException {
this.millisecondsToSleep = millisecondsToSleep;
semaphore.acquire();
}
public synchronized long simulateSleepEndsReturnTimeSlept(){
if(semaphore.availablePermits() < 0){
semaphore.release();
long slept = millisecondsToSleep;
millisecondsToSleep = null;
return slept;
}else{
return 0L;
}
}
}
public static final class SystemThreadSleeper extends ThreadSleeper{
public void sleep(long millisecondsToSleep) throws InterruptedException {
Thread.sleep(millisecondsToSleep);
}
}
}
È una soluzione / buona pratica? Mi chiedo perché non abbia mai visto qualcosa di simile. Può essere un eccesso o forse ci sono alternative migliori.