Search code examples
javadatetimejunitjacksonopenapi-generator

Jackson.InvalidDefinitionException: Cannot construct instance of java.time.OffsetDateTime in JUnit @BeforeEach


I am trying to create unit test cases for my Open-API auto-generated code. I have a date-time format which works fine in API but fails when I try to setup my JUnit test case

JUnit setup code:

@BeforeEach
public void setUp() throws IOException {
        MockitoAnnotations.initMocks(this);
        requestDTO = objectMapper.readValue(TestData.TEST_JSON, RequestDTO.class);
    }

TestData.TEST_JSON :

public static String TEST_JSON= "{\n" +
            "  \"name\": \"credit_application\",\n" +
            "  \"comments\": {\n" +
            "    \"id\": \"1\",\n" +
            "    \"userId\": \"21212\",\n" +
            "    \"taskId\": \"212\",\n" +
            "    \"time\": \"2010-07-17T02:49:58.564Z\",\n" +
            "    \"comment\": \"Hello world\"\n" +
            "  },\n" +
            "  \"id\": \"123\",\n" +
            "  \"version\": \"1.0\"\n" +
            "}";

/*
{
  "name": "credit_application",
  "comments": {
    "id": "1",
    "userId": "21212",
    "taskId": "212",
    "time": "2010-07-17T02:49:58.564Z",
    "comment": "Hello world"
  },
  "id": "123",
  "version": "1.0"
}
*/

RequestDTO (Open-API autogenerated code):

public class RequestDTO   {
  @JsonProperty("name")
  private String name;

  @JsonProperty("comments")
  private CommentDTO comments;

  @JsonProperty("id")
  private String id;

  // Constructors and Getters/Setters

}

CommentDTO (Open-API autogenerated code):

public class CommentDTO   {
  @JsonProperty("id")
  private String id;

  @JsonProperty("userId")
  private String userId;

  @JsonProperty("taskId")
  private String taskId;

  @JsonProperty("time")
  private OffsetDateTime time;

  @JsonProperty("comment")
  private String comment;

  // Constructors and Getters/Setters
}

Exception:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `java.time.OffsetDateTime` (no Creators, like default construct, exist): no String-argument constructor/factory method to deserialize from String value ('2020-07-27T02:49:58.564Z')

This date-time is used and works for application code, but not in Junit setup code.


Solution

  • You need to use JavaTimeModule to configure the ObjectMapper to deal with Java DateTime API using :

    <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
            <version>2.9.10</version>
    </dependency>
    

    Then register the module to you ObjectMapper

     ObjectMapper objectMapper = new ObjectMapper();
     objectMapper.registerModule(new JavaTimeModule());
     objectMapper.readValue(TestData.TEST_JSON, RequestDTO.class);