How to mock new Date() in java using Mockito
The right thing to do is to restructure your code to make it more testable as shown below.
Restructuring your code to remove the direct dependency on Date will allow you to inject different implementations for normal runtime and test runtime:
interface DateTime {
Date getDate();
}
class DateTimeImpl implements DateTime {
@Override
public Date getDate() {
return new Date();
}
}
class MyClass {
private final DateTime dateTime;
// inject your Mock DateTime when testing other wise inject DateTimeImpl
public MyClass(final DateTime dateTime) {
this.dateTime = dateTime;
}
public long getDoubleTime(){
return dateTime.getDate().getTime()*2;
}
}
public class MyClassTest {
private MyClass myClassTest;
@Before
public void setUp() {
final Date date = Mockito.mock(Date.class);
Mockito.when(date.getTime()).thenReturn(30L);
final DateTime dt = Mockito.mock(DateTime.class);
Mockito.when(dt.getDate()).thenReturn(date);
myClassTest = new MyClass(dt);
}
@Test
public void someTest() {
final long doubleTime = myClassTest.getDoubleTime();
assertEquals(60, doubleTime);
}
}
Mock Date object using Mockito
I don't think you are using the syntax correctly. The any
idiom is used for matching arguments when a method is called, not for specifying the return value of a mocked called. See Matchers for details on how these work.
Try providing a real date as your return value.
I gather from your line of code that you might be using Mockito incorrectly. If you are testing Manager
using a mocked Service
then your code should likely look something like:
Date testDate = new Date("01/01/1970");
Service mockedService = mock(Service.class);
when(service.getDate()).thenReturn(testDate);
testManager.setService(service);
assertEquals(testDate, testManager.getServicesDate());
In other words, you wouldn't normally be mocking a Manager
object (as implied by your code) if you are testing the Manager
class.
How to mock date in mockito?
You pass raw value there (as error already mentioned). Use matcher instead like this:
import static org.mockito.Mockito.*;
...
when(barObj.bar(eq(10), any(Date.class))
.thenReturn(10)
Mock Date() when you call SimpleDateFormat method
The "correct" way of doing this: write test-able code. And directly calling new sometimes leads to hard-to-test code. And then people need to pull out the big PowerMock(ito) hammer in order to fix that.
Alternatively, consider to learn how to write testable code; starting here.
In your case, you could give a little factory to your code under tests that generates "current" Date objects for you. You use dependency injection to get that factory into your class under test; and for testing, you mock that factory. Leading to zero need to mock calls to new.
How to compare new Date in unit test?
As I understand it is impossible to change the service and the entity. Then in such cases it is better to use ArgumentMatcher<>
in Mockito
.
Step 1 :
@AllArgsConstructor
public class EntityMatcher implements ArgumentMatcher<Entity> {
private Entity left;
@Override
public boolean matches(Entity right) {
return (left.getEventDate().getTime() - right.getEventDate().getTime() <= 1000));
}
}
Here you ovverride equals
which will be compare objects. mathces
can be ovveride
as you like. I think the difference in one second is enough.
Step 2:
verify(entityRepository).save(argThat(new EntityMatcher(new Entity(new Date(), 1, 2L))));
Other case :
Most likely, in other tests, such a situation may arise that this entity
will also need to be checked when
when(entityRepository.save(any(Entity.class))).thenReturn(new Entity(new Date(), 1, 2L));
Can't mock Date class
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());
}
}
Related Topics
How to Create an 2D Arraylist in Java
Where Is the Correct Location to Put Log4J.Properties in an Eclipse Project
How to Disable the Default Console Handler, While Using the Java Logging API
Creating Animated Gif with Imageio
Trouble with Gson Serializing an Arraylist of Pojo'S
How to Modify JSONnode in Java
Steps Needed to Use MySQL Database with Play Framework 2.0
Using an Instance of an Object as a Key in Hashmap, and Then Access It with Exactly New Object
Transactional Saves Without Calling Update Method
Find Files in a Folder Using Java
String Replacement in Java, Similar to a Velocity Template
How to Have Case Insensitive Urls in Spring MVC with Annotated Mappings
Sessiontimeout: Web.Xml VS Session.Maxinactiveinterval()