1

When i insert my business object in the database (with spring/hibernate), there are some date fields that are updated with the current date.

This is an important feature so i want to validate it in my testable specification.

The problem is that i want to see the field with the correct date, but as it's the current date, it changes every time.

I have a solution that could work but it's so hacky that i can't do it in good conscience.

It would be like this :

@Service
public class DateService {
  private Date fixedDate;

  public Date getCurrentDate() {
    if (fixedDate != null)
      return fixedDate;
    return new Date();
  }

  // setter / reset
}

And I @autowired it every time i need a new Date(). Then, when it's testing time, i fix the date so i know every "new" date would be this date.

How do you create good repeatable date based tests in your projects ?

Thanks

Maxime ARNSTAMM
  • 5,274
  • 10
  • 53
  • 76

3 Answers3

1

I would approach it in the following manner:

  1. In the test client, I would capture the current date and save it in a variable
  2. I would then invoke the service to be tested (the service should get the current date and use it to update the model)
  3. I would then invoke the service to obtain the relevant part of the model (R in CRUD); I would assume that the model representation contains the field with the date
  4. I would then write an assertion to compare 2 dates: the one I got in the test client and the one that was set by the service
Olivier Liechti
  • 3,138
  • 2
  • 19
  • 26
1

In cases when you can alter the underlying system, injecting an alternate clock implementation works well. For example, this answer shows various solutions, including Java 8's java.time.Clock interface.

For system tests, where you want to test the real implementation, instrument a Concordion spec such as:

<p>The invoice date is set to <span c:assertEquals=getInvoiceDate()>today</span></p>

Return a String value from the fixture method, containing either:

  • "today" if the date is today, or
  • a formatted date if the date is not today. This will then be shown as today20/12/2014 in the Concordion output.

Note: with this approach, be cautious of running your tests across midnight, since you run the risk of the date changing between retrieving the date and testing it.

Community
  • 1
  • 1
Nigel Charman
  • 733
  • 5
  • 9
0

To prevent having test code in your production environment, I would suggest to use a mock/stub framework to replace your DateService in your tests. For example, you could use Mockito (https://github.com/mockito/mockito) to create a test instance of DateService returning a fixed date:

Date fixedDate = new Date(); //use any settings you need for your test
DateService mockedDateService = mock(DateService.class);
when(mockedDateService.getCurrentDate()).thenReturn(fixedDate);
user3632158
  • 277
  • 1
  • 6