https://github.com/faketime-java/faketime
Fake currentTimeMillis() without class loader hacks
https://github.com/faketime-java/faketime
java junit maven testing time
Last synced: about 2 months ago
JSON representation
Fake currentTimeMillis() without class loader hacks
- Host: GitHub
- URL: https://github.com/faketime-java/faketime
- Owner: faketime-java
- License: mit
- Created: 2017-09-04T07:45:37.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2021-02-18T10:45:52.000Z (about 4 years ago)
- Last Synced: 2023-12-07T22:03:11.220Z (over 1 year ago)
- Topics: java, junit, maven, testing, time
- Language: Java
- Homepage:
- Size: 258 KB
- Stars: 106
- Watchers: 10
- Forks: 29
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.txt
Awesome Lists containing this project
- awesome-java - FakeTime
README
# FakeTime for Java
> FakeTime uses a native Java agent to replace `System.currentTimeMillis()` implementation with the one you can control using system properties.> Inspired by [arvindsv/faketime](https://github.com/arvindsv/faketime).
[](https://travis-ci.org/faketime-java/faketime)
```java
public class ExamRegistrationServiceTest implements FakeTimeMixin {
@Autowired
ExamRegistrationService examRegistrationService;
@Test
public void registrationExpiresAfterGivenPeriod() {
ExamRegistration registration = examRegistrationService.openRegistrationValidFor(Duration.ofDays(5));
offsetRealTimeByDays(5);
assertThat(registration.hasExpired()).isTrue();
}
@Test
public void registrationIsValidDuringGivenPeriod() {
ExamRegistration registration = examRegistrationService.openRegistrationValidFor(Duration.ofDays(5));
offsetRealTimeBy(Duration.ofDays(5).minusMinutes(1));
assertThat(registration.hasExpired()).isFalse();
}
@After
public void restoreRealTimeAfterTest() {
restoreRealTime();
}
}
```## Manual setup
Start faking time in 4 easy steps:
1. Download the `faketime-agent.jar` for your operating system from the [Maven Central](https://mvnrepository.com/artifact/io.github.faketime-java/faketime-agent) repository.
```xmlio.github.faketime-java
faketime-agent
0.8.0
windows32io.github.faketime-java
faketime-agent
0.8.0
windows64io.github.faketime-java
faketime-agent
0.8.0
mac32io.github.faketime-java
faketime-agent
0.8.0
mac64io.github.faketime-java
faketime-agent
0.8.0
linux32io.github.faketime-java
faketime-agent
0.8.0
linux64```
2. Unpack the `jar` to get the agent, which is `faketime.dll` on Windows and `libfaketime` on other systems.
3. Attach the agent to your Java program with following JVM arguments.
```bash
-agentpath:path/to/unpacked/faketime/binary
-XX:+UnlockDiagnosticVMOptions
-XX:DisableIntrinsic=_currentTimeMillis
-XX:CompileCommand=quiet
-XX:CompileCommand=exclude,java/lang/System.currentTimeMillis
-XX:CompileCommand=exclude,jdk/internal/misc/VM.getNanoTimeAdjustment
```
4. Use system properties to manipulate `System.currentTimeMillis()`.
```java
System.out.println(System.currentTimeMillis()); // 1234567890
System.setProperty("faketime.offset.ms", "-7890");
System.out.println(System.currentTimeMillis()); // 1234560000System.setProperty("faketime.absolute.ms", "12345");
System.out.println(System.currentTimeMillis()); // 12345
```
## Java 8 API
```xmlio.github.faketime-java
faketime-api
0.8.0
test```
In case you get tired of converting everything to milliseconds there is a Java Time based API.
```java
FakeTime.stopAt(LocalDateTime.of(2000, 11, 10, 9, 8, 7));
FakeTime.stopAt(2000, 11, 10, ZoneOffset.UTC);
FakeTime.offsetRealByMinutes(100);
FakeTime.offsetRealBy(Duration.ofHours(20));
FakeTime.restoreReal();
```
And in case you get annoyed by writing `FakeTime` all the time there is a handy mixin.
```java
public class MyTest implements FakeTimeMixin {
@Test
public void someTimeTest() {
stopTimeAt(LocalDateTime.of(2000, 11, 10, 9, 8, 7));
stopTimeAt(2000, 11, 10, ZoneOffset.UTC);
offsetRealTimeByMinutes(100);
offsetRealTimeBy(Duration.ofHours(20));
}
@After
public void restoreRealTimeAfterTest() {
restoreRealTime();
}
}
```
## JUnit rule
```xmlio.github.faketime-java
faketime-junit
0.8.0
test```
This rule calls `FakeTime.restoreReal()` after every test, so you don't have to._Note: when using `faketime-junit` you don't need to add `faketime-api` as a `test` dependency_
```java
public class MyTest implements FakeTimeMixin {
@Rule
public FakeTimeRule fakeTimeRule = new FakeTimeRule();
@Test
public void someTimeTest() {
stopTimeAt(2000, 11, 10);
assertThat(LocalDate.now()).isEqualTo(LocalDate.of(2000, 11, 10));
// next test will start with real time
}
}
```
## Maven plugin
For further convenience there is a Maven plugin that downloads and unpacks the correct agent for your operating system.
It then sets a property that you can use in `surefire` or `failsafe` plugins to attach the agent.> Full example [here](https://github.com/faketime-java/faketime/blob/master/e2e-tests/pom.xml)
```xml
org.apache.maven.plugins
maven-surefire-plugin
2.22.1
${faketime.argLine}
io.github.faketime-java
faketime-maven-plugin
0.8.0
prepare
```
## Maven + IntelliJ
IntelliJ has a cool feature that reads `argLine` from `pom.xml` and adds all arguments to the IDE test runner.
The only thing you need to do is to replace `${faketime.argLine}` with literal arguments, since IntelliJ is not aware of `${faketime.argLine}`._Note: before running tests from IntelliJ make sure `faketime-maven-plugin` has downloaded the agent, otherwise tests won't start_
> Full example [here](https://github.com/faketime-java/faketime/blob/master/e2e-tests/pom.xml)
```xmllibfaketime
faketimeBinary
windows
faketime.dll
org.apache.maven.plugins
maven-failsafe-plugin
2.22.1
-agentpath:${project.build.directory}/${faketime.binary}
-XX:+UnlockDiagnosticVMOptions
-XX:DisableIntrinsic=_currentTimeMillis
-XX:CompileCommand=quiet
-XX:CompileCommand=exclude,java/lang/System.currentTimeMillis
-XX:CompileCommand=exclude,jdk/internal/misc/VM.getNanoTimeAdjustment
io.github.faketime-java
faketime-maven-plugin
0.8.0
prepare
```
## Maven + Eclipse
_Note: before running tests from Eclipse make sure `faketime-maven-plugin` has downloaded the agent, otherwise tests won't start_`Preferences > Java > Installed JREs > Select > Edit > Default VM arguments`
```bash
# if you're on Windows
-agentpath:target/faketime.dll
-XX:+UnlockDiagnosticVMOptions
-XX:DisableIntrinsic=_currentTimeMillis
-XX:CompileCommand=quiet
-XX:CompileCommand=exclude,java/lang/System.currentTimeMillis
-XX:CompileCommand=exclude,jdk/internal/misc/VM.getNanoTimeAdjustment# if you're on macOS/Linux
-agentpath:target/libfaketime
-XX:+UnlockDiagnosticVMOptions
-XX:DisableIntrinsic=_currentTimeMillis
-XX:CompileCommand=quiet
-XX:CompileCommand=exclude,java/lang/System.currentTimeMillis
-XX:CompileCommand=exclude,jdk/internal/misc/VM.getNanoTimeAdjustment
```
## Gradle
There are no instructions for Gradle yet, but if you'll figure this out, then don't be shy to make a pull request.
Basically, you need to download and unpack the correct agent artifact and then add some JVM arguments to the test runner.