To właśnie używam. Znalazłem go w książce: Test Driven - Practical TDD and Acceptance TDD dla programistów Java autorstwa Lasse Koskela.
public interface TimeSource {
long millis();
}
public class SystemTime {
private static TimeSource source = null;
private static final TimeSource DEFAULTSRC =
new TimeSource() {
public long millis() {
return System.currentTimeMillis();
}
};
private static TimeSource getTimeSource() {
TimeSource answer;
if (source == null) {
answer = DEFAULTSRC;
} else {
answer = source;
}
return answer;
}
public static void setTimeSource(final TimeSource timeSource) {
SystemTime.source = timeSource;
}
public static void reset() {
setTimeSource(null);
}
public static long asMillis() {
return getTimeSource().millis();
}
public static Date asDate() {
return new Date(asMillis());
}
}
Należy zauważyć, że domyślnym źródłem czasu, DEFAULTSRC, jest System.currentTimeMillis(). Jest zastępowany w testach jednostkowych; jednak normalne zachowanie to standardowy czas systemowy.
To gdzie służy on:
public class SimHengstler {
private long lastTime = 0;
public SimHengstler() {
lastTime = SystemTime.asMillis(); //System.currentTimeMillis();
}
}
I tu jest test jednostki:
import com.company.timing.SystemTime;
import com.company.timing.TimeSource;
public class SimHengstlerTest {
@After
public void tearDown() {
SystemTime.reset();
}
@Test
public final void testComputeAccel() {
// Setup
setStartTime();
SimHengstler instance = new SimHengstler();
setEndTime(1020L);
}
private void setStartTime() {
final long fakeStartTime = 1000L;
SystemTime.setTimeSource(new TimeSource() {
public long millis() {
return fakeStartTime;
}
});
}
private void setEndTime(final long t) {
final long fakeEndTime = t; // 20 millisecond time difference
SystemTime.setTimeSource(new TimeSource() {
public long millis() {
return fakeEndTime;
}
});
}
W badanej jednostki, Wymieniłem źródła czasu tylko z numerem, który został ustawiony na 1000 milisekundy. To będzie służyć jako czas rozpoczęcia. Wywołując funkcję setEndTime(), wprowadzam 1020 milisekund na czas wykańczania. Dało mi to kontrolowaną różnicę czasu wynoszącą 20 milisekund.
W kodzie produkcyjnym nie ma kodu testowego, a jedynie normalny czas systemowy.
Upewnij się, że wywołasz reset po testach, aby powrócić do korzystania z metody czasu systemowego, a nie z ustawionego czasu.
Tak, to jakaś podwójna wysyłka (chyba?) byłoby idealnym podejściem, szkoda. NET sprawia, że to jest kłopotliwe. Czasami uruchamiam swój własny zegar, ale zawsze czuję, że wprowadzam złożoność. –
Brzmi bardziej jak wstrzyknięcie zależności niż podwójna wysyłka do mnie. –
Niewielka terminologia, ale myślę, że słusznie nazywa się to podwójną wysyłką lub gościem.Jego DI jest pewny, ale bierzesz również obiekt i nakazujesz mu, aby zastosował swoją politykę aktualizacji do "tego". –