Reputation: 531
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();
}
}
Upvotes: 3
Views: 6091
Reputation: 21975
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
Upvotes: -1
Reputation: 191748
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
Upvotes: 6
Reputation: 990
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.
Upvotes: 0