0

In tests i m trying to mock response from DB. Json: { description: "testDescription" contactPhone: "123456789" createDate: "18.04.2023 10:33:23" }

My POJO has field (OffsetDateTime createDate).

Here is my test

@ActiveProfiles("test") @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK, classes = ServiceRequestApp.class) @AutoConfigureMockMvc class CreateUpdateSrControllerTest { @Autowired private MockMvc mockMvc; @Autowired AbstractRestAdapter abstractRestAdapter; @MockBean SiebelDatabaseAdapter adapter; @Autowired GetSrService service; @Test void success_getSingleSR() throws Exception { DateTimeFormatter formatter = new DateTimeFormatterBuilder() .appendPattern("dd.MM.yyyy HH:mm:ss") .toFormatter(); JavaTimeModule module = new JavaTimeModule(); module.addDeserializer(OffsetDateTime.class, new CustomDeserializer(formatter)); ObjectMapper objectMapper = JsonMapper.builder() .configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false) .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) .addModule(module) .build(); ServiceRequest response = objectMapper.readValue(new File("src/test/resources/GET_response.json"), ServiceRequest.class); Mockito.when(adapter.getSingleSrV2("1-824E20I0", "1-631532350728")).thenReturn(response); mockMvc.perform(get("/service-request") .contentType(MediaType.APPLICATION_JSON) .param("serviceRequest.id", "1-824E20I0") .param("serviceRequest.number", "1-631532350728") .header("x-channel-id", "test")) .andExpect(status().isOk()) .andExpect(jsonPath("$.description").value("testDescription")) .andExpect(jsonPath("$.contactPhone").value("123456789")); } private class CustomDeserializer extends JsonDeserializer<OffsetDateTime> { private DateTimeFormatter formatter; public CustomDeserializer(DateTimeFormatter formatter) { this.formatter = formatter; } @Override public OffsetDateTime deserialize(JsonParser parser, DeserializationContext context) throws IOException, JsonProcessingException { return OffsetDateTime.parse(parser.getText(), this.formatter); } } } 

As you can see, i ve tried some methods covered on this site. But it doesnt work for me.

Here is my error:

 com.fasterxml.jackson.databind.JsonMappingException: Text '18.04.2023 10:33:44' could not be parsed: Unable to obtain OffsetDateTime from TemporalAccessor: {},ISO resolved to 2023-04-18T10:33:44 of type java.time.format.Parsed (through reference chain: ru.mts.cx.support.service.model.rest.ServiceRequest["createDate"]) at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:392) at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:351) at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.wrapAndThrow(BeanDeserializerBase.java:1821) at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:316) at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177) at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:323) at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4674) at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3494) at ru.mts.cx.support.service.controller.CreateUpdateSrControllerTest.success_getSingleSR(CreateUpdateSrControllerTest.java:76) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725) at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60) at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131) at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149) at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140) at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84) at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115) at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105) at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37) at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104) at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:214) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:210) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:66) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86) at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86) at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53) at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:71) at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38) at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11) at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35) at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235) at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54) Caused by: java.time.format.DateTimeParseException: Text '18.04.2023 10:33:44' could not be parsed: Unable to obtain OffsetDateTime from TemporalAccessor: {},ISO resolved to 2023-04-18T10:33:44 of type java.time.format.Parsed at java.base/java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:2023) at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1958) at java.base/java.time.OffsetDateTime.parse(OffsetDateTime.java:404) at ru.mts.cx.support.service.controller.CreateUpdateSrControllerTest$CustomDeserializer.deserialize(CreateUpdateSrControllerTest.java:100) at ru.mts.cx.support.service.controller.CreateUpdateSrControllerTest$CustomDeserializer.deserialize(CreateUpdateSrControllerTest.java:90) at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129) at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:314) ... 74 more Caused by: java.time.DateTimeException: Unable to obtain OffsetDateTime from TemporalAccessor: {},ISO resolved to 2023-04-18T10:33:44 of type java.time.format.Parsed at java.base/java.time.OffsetDateTime.from(OffsetDateTime.java:372) at java.base/java.time.format.Parsed.query(Parsed.java:241) at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1954) ... 79 more Caused by: java.time.DateTimeException: Unable to obtain ZoneOffset from TemporalAccessor: {},ISO resolved to 2023-04-18T10:33:44 of type java.time.format.Parsed at java.base/java.time.ZoneOffset.from(ZoneOffset.java:350) at java.base/java.time.OffsetDateTime.from(OffsetDateTime.java:361) ... 81 more 

Tried to create CustomDeserializer, add DateTimeFormatter, add @JsonFormat(pattern = "dd.MM.yyyy HH:mm:ss") above my field type OffsetDateTime

14
  • You are trying to use OffsetDateTime but not including the time zone / zone id. stackoverflow.com/questions/35298214/… Commented Apr 18, 2023 at 16:05
  • Did you mean LocalDateTime? Commented Apr 18, 2023 at 16:19
  • @geeves your url leads to branch where manual transformation is discussed. But how can i solve this error with mapper? Btw, why (DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false) configuration doesnt solve zone id question? Commented Apr 18, 2023 at 16:23
  • 1
    Maybe .parseDefaulting(ChronoField.OFFSET_SECONDS, OffsetDateTime.now().getOffset().getTotalSeconds()) in your formatter creation. java.time mavens might know a less kludgy way Commented Apr 18, 2023 at 16:59
  • 1
    If you want to use the JVM’s current default time zone, I suggest return LocalDateTime.parse(parser.getText(), this.formatter).atZone(ZoneId.systemDefault()).toOffsetDateTime();. Commented Apr 18, 2023 at 17:48

1 Answer 1

0

The type of the field createDate is OffsetDateTime. To test it your test data must contain the offset. Even if it is equal to 0. Otherwise it can't be parsed.

Solution

Adjust the formatter to contain a 'Z'

DateTimeFormatter formatter = new DateTimeFormatterBuilder() .appendPattern("dd.MM.yyyy HH:mm:ssZ") .toFormatter(); 

Add offset to the test data

createDate: "18.04.2023 10:33:23+0000" 
Sign up to request clarification or add additional context in comments.

3 Comments

And this variant is working fine, thank you! But what if in DB this field doesnt contain +0000? The type of data is DATE in DB.
If it comes without offset then your application (not only the test) should not use OffsetDateTime in the POJO. Other candidate would be LocalDateTime. However in that case the DB and application must be configured to use the same time zone.
not sure, but this date format is what i get from DB. RawMapper while parsing resultSet doing ok with it. I think it works like we discussed in the comments below my question (thanks g00se). I suppose rawMapper just adding offset by default.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.