I'm trying to test a POST endpoint in my Spring Boot application that creates a ChallengeReport. However, the response body is always empty, even though the status code is correct. I need help figuring out why the response body is not being returned as expected.
Controller
@RestController
@RequestMapping("/call")
public class UpdateController {
private ReportsService reportsService;
@Autowired
public UpdateController(ReportsService reportsService) {
this.reportsService = reportsService;
}
@PostMapping("/createChallengeReport")
@ResponseStatus(HttpStatus.CREATED)
public ResponseEntity<ChallengeReport> createChallengeReport(@RequestBody ReportDTO dto) {
ChallengeReport challengeReport = reportsService.createChallengeReport(dto);
return ResponseEntity.status(HttpStatus.CREATED).body(challengeReport);
}
//...
Service
public ChallengeReport createChallengeReport(ReportDTO dto) {
// Convert DTO to ChallengeReport entity
ModelMapper modelMapper = new ModelMapper();
ChallengeReport challengeReport = modelMapper.map(dto, ChallengeReport.class);
// Check if user exists
Optional<User> optionalUser = userRepository.findById(challengeReport.getUser().getId());
if (optionalUser.isEmpty()) {
throw new NotFoundException("User not found");
}
var user = optionalUser.get();
Optional<Challenge> optionalChallenge = challengeRepository.findById(challengeReport.getChallenge().getId());
if (optionalChallenge.isEmpty()) {
throw new NotFoundException("Challenge not found");
}
var challenge = optionalChallenge.get();
// Check if ChallengeReport already exists for the given challengeId and userId
boolean reportExists = challengeReportRepository.existsByChallengeIdAndUserId(
challengeReport.getChallenge().getId(), dto.getUserId());
if (reportExists) {
throw new AlreadyExistsException("ChallengeReport already exists");
}
var challengeSummary = challengeSummaryRepository.findByUser(user).get();
challengeSummary.setChallengeCount(challengeSummary.getChallengeCount() + 1);
challengeSummary.setPendingCount(challengeSummary.getPendingCount() + 1);
// Save and return the new ChallengeReport
challengeReportRepository.save(challengeReport);
return challengeReport;
}
Test
java.util.Date date = new Date();
@BeforeEach
public void setUp() {
user = new User();
}
// Test for createChallengeReport with status code 201
@Test
public void createChallengeReportTest() throws Exception {
challenge = new Challenge("Challenge 1", "Description 1", Unit.KM, 2.0, date,
1, 2, user, Visibility.PUBLIC);
challengeReport = new ChallengeReport(challenge, user, "Challenge 1", date,
"User 1", "Description 1");
var dto = new ReportDTO(1L, 1L, "Challenge 1", date, date, "User 1",
"Description 1", ChallengeStatus.OPEN);
given(this.reportsService.createChallengeReport(dto)).willReturn(challengeReport);
ObjectWriter ow = objectMapper.writer().withDefaultPrettyPrinter();
String requestJson = ow.writeValueAsString(dto);
this.mvc.perform(post("/call/createChallengeReport")
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON)
.content(requestJson))
.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.name").value("Challenge 1"))
.andExpect(jsonPath("$.description").value("Description 1"))
.andExpect(jsonPath("$.createdBy").value("User 1"));
}
Debugging-Console
MockHttpServletResponse:
Status = 201
Error message = null
Headers = []
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
MockHttpServletResponse:
Status = 201
Error message = null
Headers = []
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
ChallengeReport
@Entity
public class ChallengeReport {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "challenge_FK")
private Challenge challenge;
// fk of user
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "user_FK")
private User user;
private String name;
private Date startDate;
private Date endDate;
private String createdBy;
private String description;
@Enumerated(EnumType.STRING)
private ChallengeStatus status;
public ChallengeReport() {
this.status = ChallengeStatus.OPEN;
}
@Autowired
public ChallengeReport(Challenge challenge, User user, String name, Date startDate, String createdBy,
String description) {
this.user = user;
this.challenge = challenge;
this.name = name;
this.startDate = startDate;
this.endDate = null;
this.createdBy = createdBy;
this.description = description;
this.status = ChallengeStatus.OPEN;
}
Why is the response body empty even though the status code is 201 Created? What might I be missing in the setup of my test or controller to ensure the response body is returned?
dto
however it will never match as it isn't thedto
that is being send but JSON, which is turned into aReportDTO
which is a different instance an dhence it expectation fails. Falling back to the default of returningnull
.ChallengeReport
look like?ChallengeReport
. I've excluded imports, getters and setters.