How to fix system date in JUnit

I want to fix the system date

When I enter the unit test phase at work, I often want to fix the date. This time I tried to fix the time using the Mock library.

Premise: What class is the test target? ??

This time I will write a JUnit to test the following.

public class OutputDate {
    public void getDate(){
    	SimpleDateFormat sdf = new SimpleDateFormat("yyyy year MM month dd day hh hour mm minute ss second SSS millisecond");
    	System.out.println(sdf.format(new Date()));
    }
}

If all goes well, the date and time output by new Date () should be fixed!

First of all, Power Mock!

I learned from my boss that it can be achieved by the following methods.

@RunWith(PowerMockRunner.class)
@PrepareForTest({OutputDate.class, Date.class})
public class FixSysDateUsingPowerMock1 {

	OutputDate output = new OutputDate();

	@Before
	public void setUp(){
		setDatemock();
	}


	@Test
	public void test() {
		output.getDate();
	}

	/**
	 *Fix system date
	 *This method cannot fix up to milliseconds
	 */
	private static void setDatemock(){
		Calendar cal = Calendar.getInstance();
		//Set the time to 10:10:10 on January 1, 2018(Month is 0 in January)
		cal.set(2018, 0,1,10,10,10);
		try {
			PowerMockito.whenNew(Date.class).withNoArguments().thenReturn(cal.getTime());
			when(new Date()).thenReturn(cal.getTime());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

This is a method of trying to fix using the set () method of the Calendar class with the setDatemock () method. At first I thought this was fine, but ** I can't fix the milliseconds with this. ** Because there is nothing to specify up to milliseconds in the set method (in the range I searched for).

I want to output up to milliseconds with PowerMock ...

I was wondering what to do, but I wonder if I can do it well with strings? Based on the hint from my boss, I came up with the following method.


@RunWith(PowerMockRunner.class)
@PrepareForTest({ OutputDate.class, Date.class })
public class FixSysDateUsingPowerMock2 {

	OutputDate output = new OutputDate();

	@Before
	public void setUp() {
		setDatemock();
	}

	@Test
	public void test() {
		output.getDate();
	}

	/**
	 *Fix system date
	 *This method fixes up to milliseconds
	 */
	private static void setDatemock() {
		String strDate = "2018-01-01 10:10:10.111";
		//Set the time to 10:10:10 on January 1, 2018(Month is 0 in January)
		SimpleDateFormat sdFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");
		try {
			PowerMockito.whenNew(Date.class).withNoArguments().thenReturn(sdFormat.parse(strDate));
			when(new Date()).thenReturn(sdFormat.parse(strDate));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

This is a method to forcibly convert the date and time you want to fix from a character string to Date format. In this way, we were able to fix milliseconds. Congratulations ...

Is it possible to fix the date and time with JMockit?

I was completely relieved by the above method, but I had a problem when I got the coverage. It seems that the tool "Eclemma" used when acquiring coverage in Eclipse does not work well when PowerMockRunner.class is specified in the test runner. It seems to be a known problem, and it seems that it can be solved by using @Rule as shown below.

Click here for how to get coverage with Eclemma using PowerMock → https://code.i-harness.com/ja/q/1647e8c

However, at the time of the unit test, I was eager to find another way. Then I came up with the following method using the JMockit library.

@RunWith(JMockit.class)
public class FixSysDateUsingJMockit {

	//You have to add private static
	@Mocked
	private static OutputDate output = new OutputDate();

	@Before
	public void setUp() throws Exception{
		setDatemock();
	}

	@Test
	public void test() {
		output.getDate();
	}

	private  void setDatemock() throws Exception {
		String strDate = "2018-01-01 10:10:10.111";
		SimpleDateFormat sdFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");
		new CurrentTimeMock(sdFormat.parse(strDate));
	}

	/**
	 *date mock class
	 */
	public static class CurrentTimeMock extends MockUp<System>{
		Date mockTime;

		public CurrentTimeMock(Date mockTime){
			this.mockTime = mockTime;
		}

		@Mock
		public long currentTimeMillis(){
			return mockTime.getTime();
		}
	}

I'm glad I was able to fix the date and get coverage!

Recommended Posts

How to fix system date in JUnit
How to run JUnit in Eclipse
How to get date data in Ruby
How to filter JUnit Test in Gradle
[Swift] How to fix Label in UIPickerView
How to get the date in java
How to use JUnit 5
JUnit 5: How to write test cases in enum
How to use JUnit (beginner)
How to write a date comparison search in Rails
How to write Junit 5 organized
How to migrate from JUnit4 to JUnit5
[Creating] How to use JUnit
How to select a specified date by code in FSCalendar
How to use Lombok in Spring
How to iterate infinitely in Ruby
[Rails] How to write in Japanese
How to run Ant in Gradle
How to master programming in 3 months
How to learn JAVA in 7 days
How to get parameters in Spark
How to install Bootstrap in Ruby
How to use InjectorHolder in OpenAM
How to introduce jQuery in Rails 6
How to use classes in Java?
How to name variables in Java
How to set Lombok in Eclipse
How to concatenate strings in java
How to install Swiper in Rails
How to fix garbled Japanese characters in JAVA (including Arduino IDE)
How to think about class design (division) in a business system (1)
[swift5] How to specify color in hexadecimal
How to implement search functionality in Rails
How to implement Kalman filter in Java
How to change app name in rails
How to use custom helpers in rails
How to reflect seeds.rb in production environment
How to use named volume in docker-compose.yml
How to insert a video in Rails
How to standardize header footer in Thymeleaf
How to add jar file in ScalaIDE
How to use Docker in VSCode DevContainer
How to use MySQL in Rails tutorial
How to implement coding conventions in Java
How to embed Janus Graph in Java
[rails] How to configure routing in resources
How to map tsrange type in Hibernate
How to implement ranking functionality in Rails
How to use environment variables in RubyOnRails
How to test private scope with JUnit
How to implement asynchronous processing in Outsystems
How to publish a library in jCenter
How to specify id attribute in JSF
Understand in 5 minutes !! How to use Docker
How to overwrite Firebase data in Swift
How to use credentials.yml.enc introduced in Rails 5.2
How to assemble JSON directly in Jackson
How to execute multiple commands in docker-compose.yml
[For beginners] How to debug in Eclipse
How to use ExpandableListView in Android Studio
How to display error messages in Japanese