0

I am writing a unit test to verify that both the ISO8601Utils (deprecated class which I replaced with SimpleDateFormat) and SimpleDateFormat has the same format.

My class:

    public static class ISO8601DateFormat extends DateFormat {

    public static final long serialVersionUID = 3549786448500970210L;

    public ISO8601DateFormat() {}

    @Override
    public StringBuffer format(Date date, StringBuffer  
    toAppendTo, FieldPosition fieldPosition) {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-
        dd'T'HH:mm:ss.SSS'Z'");
        String value = dateFormat.format(date);
        //This used to be ISO8610Utils.format(date, true) which  
        //is now deprecated and I replaced it with the new one. I  
        //want to verify this part so that the newly replaced 
        //dateFormat still returns the same formatted output as the 
        //ISO8610Utils

        toAppendTo.append(value);
        return toAppendTo;
    }

    public Date parse(String source, ParsePosition pos) {
        pos.setIndex(source.length());
        return ISODateTimeFormat.dateTimeParser().parseDateTime(source).toDate();
    }

    public Object clone() {
        return this;
    }

    public String toString() {
        return this.getClass().getName();
    }
}

My test method:

  @Test
    public void testDateFormat() {
     df = new DefaultHttpClientUtil.ISO8601DateFormat();
     Date date = new Date();
     //df.setTimeZone(TimeZone.getTimeZone("GMT")); I'm getting NPE   
     for this line

    assertThat(df.format(date)).isEqualTo(ISO8601Utils.format(date, 
    true));
  }

However, I am getting null pointer exception for the commented line. I assume it has to do with injecting or mocking object, but I am not sure how I should approach this problem.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
lovprogramming
  • 593
  • 11
  • 24
  • 1
    Excuse me, IMHO that appears a bit ironic: replacing a deprecated class with the notoriously troublesome and long outdated `SimpleDateFormat` class. Why not take the step and migrate to [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/) now you’re at it? It also excels at ISO 8601. Use the `Instant` class instead of `Date` and its `parse` and `toString` methods for parsing and formatting, or a `DateTimeFormatter`. – Ole V.V. Feb 20 '19 at 03:29
  • 1
    @louprogramming, do you use `Java 8` or higher? – Michał Ziober Feb 20 '19 at 10:20

1 Answers1

0

You're actually applying delegation pattern, so that it's essential to override setTimeZone method to forward request to the SimpleDateFormat object, just as follows:


public static class ISO8601DateFormat extends DateFormat {
    ...

    // MUST make dateFormat reusable.
    private final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");

    @Override
    public void setTimeZone(TimeZone zone)
    {
        dateFormat.setTimeZone(zone);
    }
}

Jerry Chin
  • 657
  • 1
  • 8
  • 25
  • Correct answer. IMHO it’s better to avoid using the poorly designed and long outdated `DateFormat` class altogether. – Ole V.V. Feb 20 '19 at 03:16