Lors de l'utilisation de certains DateFactory modèle semble beau, il ne couvre pas les bibliothèques que vous ne pouvez pas contrôler - imaginer la Validation de l'annotation @Passé avec la mise en œuvre en s'appuyant sur le Système.currentTimeMillis (il y a une telle).
C'est pourquoi nous utilisons jmockit de se moquer de l'heure du système directement:
import mockit.Mock;
import mockit.MockClass;
...
@MockClass(realClass = System.class)
public static class SystemMock {
/**
* Fake current time millis returns value modified by required offset.
*
* @return fake "current" millis
*/
@Mock
public static long currentTimeMillis() {
return INIT_MILLIS + offset + millisSinceClassInit();
}
}
Mockit.setUpMock(SystemMock.class);
Parce qu'il n'est pas possible de se rendre à l'original unmocked valeur de millis, nous utilisons nano minuterie au lieu de cela - ce n'est pas lié à l'horloge du mur, mais de temps relatif suffit ici:
// runs before the mock is applied
private static final long INIT_MILLIS = System.currentTimeMillis();
private static final long INIT_NANOS = System.nanoTime();
private static long millisSinceClassInit() {
return (System.nanoTime() - INIT_NANOS) / 1000000;
}
Il est documenté problème, qu'avec HotSpot, le temps sera de retour à la normale après un certain nombre d'appels - voici le rapport: http://code.google.com/p/jmockit/issues/detail?id=43
Pour surmonter cela, nous devons tourner sur un HotSpot optimisation - exécution de la JVM avec cet argument -XX:-Inline
.
Même si cela peut ne pas être idéal pour la production, il est tout simplement parfait pour les tests et il est tout à fait transparente pour l'application, en particulier lorsque DataFactory ne rend pas le sens des affaires et est introduit seulement en raison de tests. Il serait agréable d'avoir intégré en option JVM pour s'exécuter dans un temps différent, trop mauvais, il n'est pas possible sans hacks de ce genre.
Histoire complète est dans mon blog ici:
http://virgo47.wordpress.com/2012/06/22/changing-system-time-in-java/
Complète, pratique de classe SystemTimeShifter est fourni dans le post. La classe peut être utilisée dans vos tests, ou il peut être utilisé comme la première classe principale avant votre véritable classe principale très facilement afin d'exécuter votre application (ou même l'ensemble du serveur d'applications) dans un autre temps. Bien sûr, cela est destiné à des fins de test surtout, mais pas pour un environnement de production.
ÉDITION juillet 2014: JMockit beaucoup changé ces derniers temps et vous êtes lié à l'utilisation JMockit 1,0 à utiliser correctement (IIRC). Certainement ne pouvez pas mettre à niveau à la version la plus récente où l'interface est complètement différente. Je pensais à l'in-lining, juste le nécessaire, mais comme nous n'avons pas besoin de cette chose dans nos nouveaux projets, je ne suis pas le développement de cette chose.