pact-foundation / pact-jvm

JVM version of Pact. Enables consumer driven contract testing, providing a mock service and DSL for the consumer project, and interaction playback and verification for the service provider project.
https://docs.pact.io
Apache License 2.0
1.08k stars 479 forks source link

Java Instant is treated as Decimal #1754

Open ftrela-aptitude opened 9 months ago

ftrela-aptitude commented 9 months ago

Hi! I have the following scenario: I have a request with a body that contains a date constructed using Java Instant. When constructing a PactDslJsonBody, I expect to be able to verify that field using datetime() method (it used to work before V4Pact). Currently, I am getting the following error:

12:23:29.768 [HTTP-Dispatcher] WARN a.c.d.p.c.matchers.MatcherExecutor - Failed to parse 1703329200.000000000 with 'yyyy-MM-dd'T'HH:mm:ss' using java.time.format.DateTimeFormatter. Exception was: Text '1703329200.000000000' could not be parsed at index 0. Will attempt to parse using org.apache.commons.lang3.time.DateUtils to guarantee backwards compatibility with versions < 4.1.1. Please update your patterns in your pact tests as this may not be supported in future versions.

As a result, the test is failed and no pact is generated. If I replace datetime() with decimalType() then it works but it's quite misleading.

rholshausen commented 9 months ago

There is a datetime method which accepts a Java Instant: https://github.com/pact-foundation/pact-jvm/blob/master/consumer/src/main/kotlin/au/com/dius/pact/consumer/dsl/PactDslJsonBody.kt#L912

ftrela-aptitude commented 9 months ago

This is precisely the method that I am using: .datetime("date", DATE_TIME_FORMAT, TimeZone.getDefault(), date) where "date" is an Instant created according to DATE_TIME_FORMAT constant. It produces the output below:

09:02:22.078 [HTTP-Dispatcher] WARN a.c.d.p.c.matchers.MatcherExecutor - Failed to parse 1672567200.000000000 with 'yyyy-MM-dd'T'HH:mm:ss'Z'' using java.time.format.DateTimeFormatter. Exception was: Text '1672567200.000000000' could not be parsed at index 0. Will attempt to parse using org.apache.commons.lang3.time.DateUtils to guarantee backwards compatibility with versions < 4.1.1. Please update your patterns in your pact tests as this may not be supported in future versions. 09:02:22.103 [HTTP-Dispatcher] ERROR a.c.d.pact.consumer.BaseMockServer - PartialRequestMatch: POST request for task registration: Expected 1672567200.000000000 to match a datetime of 'yyyy-MM-dd'T'HH:mm:ss'Z'': Unable to parse the date: 1672567200.000000000

rholshausen commented 8 months ago

You have the parameters the wrong way around. The date is the third parameter, and the TimeZone the fourth one.

ftrela-aptitude commented 8 months ago

You have the parameters the wrong way around. The date is the third parameter, and the TimeZone the fourth one.

As of version 4.4.3, there are two datetime() methods that accept Date object: one with the parameters order that I included in my previous reply, and another with the order you supplied. Both give me the same parsing error.

rholshausen commented 8 months ago

If you change your code to .datetime("date", DATE_TIME_FORMAT, date) what happens?

ftrela-aptitude commented 8 months ago

I get the same warning as with other methods:

Failed to parse 1672567200.000000000 with 'yyyy-MM-dd'T'HH:mm:ss'Z'' using java.time.format.DateTimeFormatter. Exception was: Text '1672567200.000000000' could not be parsed at index 0. Will attempt to parse using org.apache.commons.lang3.time.DateUtils to guarantee backwards compatibility with versions < 4.1.1. Please update your patterns in your pact tests as this may not be supported in future versions.

rholshausen commented 8 months ago

Can you confirm the format that your request is being made with? That error could be indicating your application is sending through the value 1672567200.000000000 for that field while the mock server is expecting a value formatted with 'yyyy-MM-dd'T'HH:mm:ss'Z