I am trying to mock Calendar.getInstance()
method using JMockit. This is the first time I am mocking anything.
Below is my method which gives me the date of either recent Monday
or recent Thursday
in the format of YYYYMMDD
.
Today is Sunday, so it should return date for Thursday in the format of YYYYMMDD
so it will be - 2014027
public static String getCorrectDate() {
Calendar cal = Calendar.getInstance();
try {
int dow = cal.get(Calendar.DAY_OF_WEEK);
switch (dow) {
case Calendar.THURSDAY:
case Calendar.FRIDAY:
case Calendar.SATURDAY:
case Calendar.SUNDAY:
while (cal.get(Calendar.DAY_OF_WEEK) != Calendar.THURSDAY) {
cal.add(Calendar.DATE, -1);
}
break;
case Calendar.MONDAY:
case Calendar.TUESDAY:
case Calendar.WEDNESDAY:
while (cal.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY) {
cal.add(Calendar.DATE, -1);
}
break;
}
} catch (Exception ex) {
// log error
}
return toDateFormat.format(cal.getTime());
}
So my question is how do I mock the Calendar.getInstance
method using JMokcit so that I can easily junit getCorrectDate
method?
I have never mocked it before so I am facing some problem?
Can anyone provide a simple example if possible on my example?
I am trying to do it like this but it is complaining me on MockClass
as it is not able to resolve.. I have added the maven dependency of JMockit as well
@MockClass(realClass = Calendar.class)
class CalendarMock {
private int hour;
private int day;
private int minute;
public CalendarMock(int day, int hour, int minute) {
this.hour = hour;
this.day = day;
this.minute = minute;
}
@Mock
public int get(int id) {
if (id == Calendar.HOUR_OF_DAY) {
return hour;
}
if (id == Calendar.DAY_OF_WEEK) {
return day;
}
if (id == Calendar.MINUTE) {
return minute;
}
return -1;
}
}
Rather than try to mock a static method here, I would strongly recommend introducing a Clock
interface along these lines:
public interface Clock {
Date now(); // Or long, or Instant if you're using Joda Time
}
Then you can have a production implementation which uses new Date()
or System.currentTimeMillis
, and a test implementation where you can set "the current time". Pass your clock to the method, or make it an instance method and "configure" the instance (e.g. in the constructor) with the appropriate clock.
The Clock
interface makes your code much simpler to test in my experience, without having to rely on relatively advanced mocking features for mocking static methods.
So your production code would become something like:
public static String getCorrectDate(Clock clock) {
Calendar cal = new GregorianCalendar();
cal.setTimeZone(...); // Which time zone are you interested in?
cal.setTime(clock.now()); // Or cal.setTimeInMillis(clock.now());
// ... logic as before
}
Now you can test that with lots of different dates and times.
See more on this question at Stackoverflow