0

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?

4
  • 1
    You are writing an expectation to your dto however it will never match as it isn't the dto that is being send but JSON, which is turned into a ReportDTO which is a different instance an dhence it expectation fails. Falling back to the default of returning null.
    – M. Deinum
    Commented May 27 at 6:47
  • How does your ChallengeReport look like? Commented May 27 at 7:52
  • I've added the ChallengeReport. I've excluded imports, getters and setters. Commented May 27 at 8:04
  • Try it again with implementing equals/hashcode. Commented May 27 at 9:05

0