4

I am trying to mock System.currentTimeMillis using jmockit1.43 using below code

private static class SystemMock extends MockUp<System>{
    @Mock
    public static long currentTimeMillis() {
        return ourMockCurrentTime;
    }
}

But I am getting below error when running my test:

00:01:37.658110 [.]     [junit] Exception in thread "main" java.lang.UnsatisfiedLinkError: java.lang.System.currentTimeMillis()J
00:01:37.658185 [.]     [junit]     at java.base/java.lang.System.currentTimeMillis(Native Method)
00:01:37.658188 [.]     [junit]     at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.run(JUnitTestRunner.java:544)
00:01:37.658228 [.]     [junit]     at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.launch(JUnitTestRunner.java:1196)1548910897.658231: 
00:01:37.658280 [.]     [junit]     at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(JUnitTestRunner.java:1041)

Is there a way to resolve this?

Stefan Zobel
  • 3,182
  • 7
  • 28
  • 38
learner
  • 1,952
  • 7
  • 33
  • 62

1 Answers1

1

The only way to avoid the issue is to apply the mockup ("fake") for the whole test run, by setting the fakes system property (-Dfakes=your.fully.qualified.name.SystemMock) in the command line or Maven/Gradle test execution configuration.

The underlying reason is that the java.lang.System class requires a call to an internal "registerNatives()" method (or "initIDs()" in certain other classes), in order for the original definition of the class (after it's done being faked) to be restored. Other classes in the JDK which also have native methods don't have such a method. JMockit dropped the call in recent versions for JDK 9+ compatibility, and also because it was a hack only made necessary because of JDK idiosyncrasies (which should be solved within the JDK itself).

Rogério
  • 16,171
  • 2
  • 50
  • 63