Reputation: 6755
I have created a controller which actually ends in an error in my testcase. There are few other controllers which I have made the same way and there the tests work. Currently I am looking for a solution but I am stuck since hours.
The following testcase fails because it results in an http error 500 instead of 200
@ActiveProfiles("Test")
@AutoConfigureMockMvc
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@Transactional
@SpringBootTest
. . .
@Test
public void whenCreateCustomer_ThenReturnIt() throws Exception {
String customerName = "foobar2";
MvcResult result = mvc.perform(post(REST_CUSTOMERS)
.header(HEADER_AUTH_KEY, authTokenAdminUser.getToken())
.contentType(MediaType.APPLICATION_JSON)
.content("{\n" +
" \"name\": \""+ customerName + "\"" +
"}")
)
.andExpect(status().isOk())
.andReturn();
String responseString = result.getResponse().getContentAsString();
CustomerEntity customer = objectMapper.readValue(responseString, CustomerEntity.class);
assertThat(customer).isNotNull();
assertThat(customer.getName()).isEqualTo(customerName);
assertThat(customer.getCreated()).isNotNull();
}
Here is the method under test. I have debugged it, and it looks good. The entity has been created and also it comes to the point where the ResponseEntity should return ok with the entity in its body. Also I have evaluated this return ResponseEntity.ok().body(createdCustomer.get()); in the debugger and it worked.
@Override
@PostMapping
public ResponseEntity<CustomerDTO> create(@RequestBody CustomerDTO dto) {
dto.setId(uidService.getNextUidScServer());
if (dto.getCreated() == null){
dto.setCreated(LocalDateTime.now());
}
Optional<CustomerDTO> createdCustomer = customerService.create(dto);
if (createdCustomer.isPresent()){
return ResponseEntity.ok().body(createdCustomer.get());
}
else{
return ResponseEntity.badRequest().build();
}
}
In the stacktrace I found this, which I think is my problem. But I have actually no idea how to solve it.
Async:
Async started = false
Async result = null
Resolved Exception:
Type = org.springframework.http.converter.HttpMessageNotWritableException
Here is the entity
@NoArgsConstructor
@AllArgsConstructor
@Data
@Entity
@Builder
@Table(name = "Customer")
public class CustomerEntity {
@Id
@Column(name = "uid")
private Long id;
@Column(name = "name")
private String name;
@Column(name = "created")
private LocalDateTime created;
@OneToMany(
mappedBy = "customer",
cascade = CascadeType.ALL,
orphanRemoval = true)
List<PenEntity> pen;
Here the dto
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CustomerDTO {
private Long id;
private String name;
@JsonDeserialize(using = LocalDateDeserializer.class)
@JsonSerialize(using = LocalDateSerializer.class)
private LocalDateTime created;
@JsonIgnore
private List<PenEntity> pen;
}
From the error message it looks like there is a problem with the json mapping. Any idea?
Upvotes: 1
Views: 1045
Reputation: 2850
For the message converter, and you are not using the correct Serializer
. You must use the LocalDateTimeSerializer
and not the LocalDateSerializer
.
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CustomerDTO {
private Long id;
private String name;
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonSerialize(using = LocalDateTimeSerializer.class)
private LocalDateTime created;
@JsonIgnore
private List<PenEntity> pen;
}
You said you used breakpoints. For the future, if you have an exception you don"t understand, use a breakpoint in the constructors of this exception. Then, use the stack trace to identify which class throws the exception, and how you can fix it.
In my debugger, I saw this:
"Could not write JSON: class java.time.LocalDateTime cannot be cast to class java.time.LocalDate (java.time.LocalDateTime and java.time.LocalDate are in module java.base of loader 'bootstrap')"
You are also suppose to have getters, but as I understood, @Data
from Lombok generates them. So you should be good.
Upvotes: 2