2

I've been reading some answers on here about using PowerMock to mock the System Date function in Java, but it seems that it's necessary to add the annotations to the actual class being tested. Let me set this question up a bit. I'm interning at a large corporation doing unit testing on a system with Spring, JUnit, Mockito, etc. My current task at hand is testing an endpoint that has a dependency on the current time against a DB (kind of like checking for an expiration date).

My question is: is it possible or intuitive to mock the System Date in a test class without touching the main source code? I don't want to modify the source code; even though it's on a testing environment I'd rather just keep it untouched. Or would it make more sense to just modify a DB entry to change the date, perform my test, and then use a transactional test rollback? Thanks a bunch!

The class I'm trying to mock is: java.util.Date cDate = new java.util.Date();

Igor
  • 33,276
  • 14
  • 79
  • 112
jmeanor
  • 158
  • 1
  • 17
  • "is it possible or intuitive to mock the System Date in a test class without touching the main source code?" <-- yes, use parameterized tests. However, given that you are using JUnit, it is not going to be easy. Had you been using TestNG, it would have been a breeze. – fge Jun 24 '13 at 12:46
  • How are you determining the system date? new Date()? Calendar.getInstance()? I don't hitnk you'd need to modify the class under test in either of these cases. Can you share the class under test? ( or the bit you need to mock at least? ) – DaveH Jun 24 '13 at 12:49
  • I edited my question; I want to mock java.util.Date() – jmeanor Jun 24 '13 at 12:53
  • This is in essence the same question as, take a look at the Joda-Time or DateSupplier answers: http://stackoverflow.com/questions/17229525/setting-time-and-date-in-junit-test-fixture/17233325#17233325 – John B Jun 24 '13 at 13:04
  • Also, I'm not directly testing Date(). Date is returned to another function that does a DB transaction to retrieve the correct record which is then returned as a response to the endpoint. I think this makes things even more complicated.. – jmeanor Jun 24 '13 at 13:06
  • 1
    There's something more to this question. Mocking a Date is nothing more than mock(Date.class), right? :) So what's the 'next step' in your question? Also, have you seen this? http://stackoverflow.com/questions/11887799/how-to-mock-new-date-in-java-using-mockito – Tony R Jun 24 '13 at 16:24
  • Thanks for all the help, guys. I think I'm on the right track using PowerMock to actually mock the calling method to Date(). Now I'm into a different issue altogether! =___= :P – jmeanor Jun 24 '13 at 17:58

1 Answers1

0

I know it is not a simple solution but you can use byteman (https://community.jboss.org/wiki/ABytemanTutorial) to fast forward the date the amount of days found in a system property. Copy this in a file named addDaysToJvmDate.btm:

RULE Calling java.util.Date()
CLASS java.util.Date
METHOD <init>()
AT EXIT
IF TRUE
DO $0.fastTime = java.lang.System.currentTimeMillis() + (86400000 *    java.lang.Long.parseLong(java.lang.System.getProperty("addDays")));
ENDRULE

and start your JVM using:

java - javaagent:${BYTEMAN_HOME}/lib/byteman.jar=script:addDaysToJvmDate.btm,boot:${BYTEMAN_HOME}/lib/byteman.jar -cp yourclasspath yourapp
Ale Sequeira
  • 2,039
  • 1
  • 11
  • 19