I am writing unit tests using TestNG. The problem is when I mock System.currentTimeMillis, it returns the actual value instead of the mocked one. Ideally, it should return 0L, but it returns the actual value. What should I do to proceed?
class MyClass{
public void func1(){
System.out.println("Inside func1");
func2();
}
private void func2(){
int maxWaitTime = (int)TimeUnit.MINUTES.toMillis(10);
long endTime = System.currentTimeMillis() + maxWaitTime; // Mocking not happening
while(System.currentTimeMillis() <= endTime) {
System.out.println("Inside func2");
}
}
}
@PrepareForTest(System.class)
class MyClassTest extends PowerMockTestCase{
private MyClass myClass;
@BeforeMethod
public void setup() {
MockitoAnnotations.initMocks(this);
myclass = new MyClass();
}
@Test
public void func1Test(){
PowerMockito.mockStatic(System.class)
PowerMockito.when(System.currentTimeMillis()).thenReturn(0L);
myclass.func1();
}
}
Make a package constructor that you can pass in a java.time.Clock
class MyClass{
private Clock clock;
public MyClass() {
this.clock = Clock.systemUTC();
}
// for tests
MyClass(Clock c) {
this.clock = c;
}
Then mock that for tests, and use this.clock.instant()
to get the clock's time
You need to add the annotation @RunWith(PowerMockRunner.class)
to the class MyClassTest
.
Nevertheless, I would advise to refactor the code to use java.time.Clock
, instead of mocking.
Instead of using PowerMock
, you can use Mockito
which also has a mockStatic
method
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>3.9.0</version>
<scope>test</scope>
</dependency>
See this answer for an example with LocalDate
Here is how it would look like in your case
try(MockedStatic<System> mock = Mockito.mockStatic(System.class, Mockito.CALLS_REAL_METHODS)) {
doReturn(0L).when(mock).currentTimeMillis();
// Put the execution of the test inside of the try, otherwise it won't work
}
Notice the usage of Mockito.CALLS_REAL_METHODS
which will guarantee that whenever System
is invoked with another method, it will execute the real method of the class
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.