Mahmoud Saleh
Mahmoud Saleh

Reputation: 33605

Can't mock Date class

i am using mockito and i have a custom date class and i want to be able to mock this date class in my test class, so i tried the following:

    MVDate date = Mockito.mock(MYDate.class);
    Mockito.when(date.get(Calendar.MONTH)).thenReturn(5);

MYDate Class:

public class MYDate extends GregorianCalendar implements Comparable<Calendar> {

public MYDate() {
        setTime(new Date());
    }

}

but when trying to print the new MYDate(); it always prints the current date. please advise how should i mock the calendar class so that i can test on specific date for all methods who create new data instance.

Upvotes: 0

Views: 3263

Answers (4)

Dawood ibn Kareem
Dawood ibn Kareem

Reputation: 79838

Please note: I wrote this answer in 2013. Things are a bit different now. Basil Bourque's answer is the correct one.

I would use a Factory class to make the Date objects, rather than using new Date(). Have a second constructor for MyDate where you can pass the Factory. Then use a mock of the Factory, which you can set up to return whatever date you like.

public class DateFactory{
    public Date makeDate(){
        return new Date();
    }
}

-----------------------------------

public class MyDate extends GregorianCalendar implements Comparable<Calendar>{

    public MyDate(){
        this(new DateFactory());
    }

    MyDate(DateFactory factory){
        setTime(factory.makeDate());
    }
}

Upvotes: 5

Basil Bourque
Basil Bourque

Reputation: 338564

Java 8 java.time.Clock Class

The new java.time.* package in Java 8 includes a Clock class for this purpose of mocking the date-time during development and testing.

Joda-Time

As I recall, the popular Joda-Time framework also has a facility for faking the clock.

Converting

You can easily convert between the date-time objects of both those frameworks and the java.util.Date class as needed for interoperability.

Upvotes: 1

John B
John B

Reputation: 32949

So the need to write unit tests against code that gets the current date is very common. I fought against it numerous times and finally wrote a solution. My solution is to have a DateSupplier that wraps the call to new Date(). I then have a test class called DateController that allows unit tests to control what value DateSupplier returns.

Here are the links: DateSupplier

DateController

DateSupplier is written with a static method to get the Date. This prevents coders from having to import an instance all over the place.

DateController is written as a Rule that rests the behavior of DateSupplier back to the default behavior of returning new Date().

Upvotes: 2

Swyish
Swyish

Reputation: 23

In your code, you are mocking a specific method 'cal.get()'.

assertEquals(cal.get(Calendar.MONTH), 5);

In this case, the above statement will be true, but cal.getTime() would return something different. Did you mean to mock cal.getTime() instead?

Upvotes: 0

Related Questions