1

I'm trying to mock my getParams(), reason of System.currentTimeMillis()


    public HashMap<String, String> getParams() {
        HashMap<String, String> params = new HashMap<>();
        params.put("page[number]", "0");
        params.put("page[size]", "20");
        params.put("filter[orders][state]", "NEW");
        params.put("filter[orders][creationDate][$ge]", String.valueOf(System.currentTimeMillis()-7000)); // 7000 - 10 days
        params.put("filter[orders][creationDate][$le]", String.valueOf(System.currentTimeMillis()));
        params.put("filter[orders][status]", "APPROVED_BY_BANK");
        params.put("filter[orders][signatureRequired]", "false");
        params.put("filter[orders][deliveryType]", "DELIVERY");
        params.put("include[orders]", "user");
        params.put("include[orders]", "entries");
        return params;
    }

This is my service which sends current time but when i'm trying to test it's generate another time which differs from service's and test. This gives me different result and I can't check if it working fine.

I tried to mock my method, but in the runtime it doesnt mock

RequestService myService = Mockito.spy(requestService);
        HashMap<String, String> params = new HashMap<>();
        params.put("page[number]", "0");
Mockito
                .doReturn(params)
                .when(myService).getParams();
   
//Mockito
                //.when(myService.getParams())
               // .thenReturn(params);

Any suggestions to fix my problem?

-----------------EDIT I solved my problem with:

  public Date truncToSec(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.MILLISECOND, 0);
        c.set(Calendar.SECOND, 0);
        Date newDate = c.getTime();
        return newDate;
Date currnetTime = new Date(System.currentTimeMillis() - 777600000) ;
currnetTime = truncToSec(currnetTime);
params.put("filter[orders][creationDate][$ge]", String.valueOf(currnetTime.toInstant().toEpochMilli())); // 777600000 - 10 days

but if you have better solution you are welcome.

We We
  • 11
  • 3
  • If there is a case for working with another time, then you should not hard-code the current time in the first place. Refactor your code such that the time is a parameter of that method. – pxcv7r Apr 19 '21 at 06:11
  • you may want to look at this thread https://stackoverflow.com/questions/52830441/junit5-mock-a-static-method – pratap Apr 19 '21 at 06:12
  • "7000 - 10 days" that seems a bit shorter than 10 days, it's just 7 seconds. – Andy Turner Apr 19 '21 at 06:13
  • @pxcv7r the problem is that both time in service and test should be the same – We We Apr 19 '21 at 06:50

2 Answers2

1

I don't know whether it's the preferred method but we have a Test-Implementation of java.time.Clock and the classes under test provide a package-private constructor, via which you can hand in this clock. In the Default case for production, the Clock.systemDefaultZone() or similar will be used.

Then in your case you wouldn't use System.currentTimeMillis() but clock.millis() which you can easily manage from your test.

PS: I'm not familiar with the newest JUnit-Version yet but I think I read something, that there you could even mock static methods. Maybe this is something to look into but I don't give any guarantees yet.

Christian
  • 1,437
  • 2
  • 8
  • 14
0

You can't achieve this using Mockito, because this requires mocking of static methods, which is not supported by Mockito.

As a possible solution, you can try to

geobreze
  • 2,274
  • 1
  • 10
  • 15
  • 1
    FYI: Recent Mockito versions [allow mocking static methods](https://rieckpil.de/mocking-static-methods-with-mockito-java-kotlin/). – rieckpil Apr 19 '21 at 08:54