The error was resolved during the springboot controller test, but I don't know the cause

Viewed 31

The error was resolved during the springboot controller test, but I don't know the cause

test environment

  • JAVA 8
  • SPRING BOOT
  • INTELLIJ
  • H2DB

Below is the code of the controller stage.

private MonsterEntity defaultMonster = MonsterEntity.builder()
            .id(1L)
            .monsterLevel(BABY)
            .monsterType(FLY)
            .statusCode(StatusCode.HEALTHY)
            .ssn("12345612345123")
            .name("BabyMonster")
            .age(3)
            .height(170)
            .weight(73)
            .build();

private CreateMonsterDto.Request getCreateRequest() {
            return CreateMonsterDto.Request.builder()
                    .id(1L)
                    .monsterLevel(BABY)
                    .monsterType(FLY)
                    .statusCode(StatusCode.HEALTHY)
                    .ssn("12345612345123")
                    .name("BabyMonster")
                    .age(3)
                    .height(170)
                    .weight(73)
                    .build();
}

@Test
@DisplayName("Monster Created Test")
void createMonster() throws Exception {
    given(mMakerService.createMonster(getCreateRequest()))
            .willReturn(CreateMonsterDto.TestResponse.fromEntity(defaultMonster));
    
    CreateMonsterDto.Response result = mMakerService.createMonster(getCreateRequest());
    
    mockMvc.perform(
                    post("/create-monster")
                            .contentType(contentType)
                            .content(new ObjectMapper().writeValueAsString(result)))
            .andExpect(status().isOk())
            .andDo(print())
            .andReturn();
    then(mMakerService).should(times(2)).createMonster(getCreateRequest());
}

given(mMakerService.createMonster(getCreateRequest())) and

CreateMonsterDto.Response result = mMakerService.createMonster(getCreateRequest());

All of them are returning the same null value.

The solution to this problem was to add @EqualsAndHashCode Annotation to DtoRequest.

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Builder
@EqualsAndHashCode(of = "id")
public static class Request {

    @NotNull
    private Long id;

    @NotNull
    private MonsterLevel monsterLevel;

    @NotNull
    private MonsterType monsterType;

    @NotNull
    private StatusCode statusCode;

    @NotNull
    @Size(min = 13, max = 15, message = "ssn max_size 14")
    private String ssn;

    @NotNull
    @Size(min = 3, max = 100, message = "name size must 3~100")
    private String name;

    @NotNull
    @Min(0)
    @Max(100)
    private Integer age;

    @NotNull
    @Min(150)
    @Max(300)
    private Integer height;

    @NotNull
    @Min(50)
    @Max(500)
    private Integer weight;
}

mMakerService.createMonster(getCreateRequest()); Is it a problem by taking out the address reference value, not the content, from the ?

Below is the code of the service stage.

public CreateMonsterDto.Response createMonster(
            CreateMonsterDto.Request request
    ) {
    validateCreateMonsterRequest(request);

    return CreateMonsterDto.Response.fromEntity(
            monsterRepository.save(
                    createMonsterFromRequest(request)
            )
    );
}

private MonsterEntity createMonsterFromRequest(CreateMonsterDto.Request request) {
   return MonsterEntity.builder()
        .id(1L)
        .monsterLevel(request.getMonsterLevel())
        .monsterType(request.getMonsterType())
        .statusCode(request.getStatusCode())
        .ssn(request.getSsn())
        .name(request.getName())
        .age(request.getAge())
        .height(request.getHeight())
        .weight(request.getWeight())
        .build();
}

When I ran this process in ServiceTest, there was no problem.

I would like to know the cause of this problem. Help. Sorry for the poor question. I'm using a translator.

I'm looking for a problem while debugging, but when I debug in ControllerTest, I can't debug until the service stage...

1 Answers

With

given(mMakerService.createMonster(getCreateRequest()))
    .willReturn(CreateMonsterDto.TestResponse.fromEntity(defaultMonster));

you tell the mocking framework to return the default monster from the mocked mMakerService when it is called with the request returned from getCreateRequest() as parameter.

Then you call the mocked mMakerService inside your test passing the result of another call to getCreateRequest(). The result is null because the two calls to getCreateRequest() will return two separate instances of the request. Without a proper implementation of equals() the two requests will be regarded as non-equal, because they are different instances and have therefore different references. By adding @EqualsAndHashCode to the request class you have made sure that the two instances are now regarded as equal.

There is another problem with your code. Calling the mock inside your test (see above) is not making any sense. You told the mock to return a specific default monster. Calling the mock will just return what you told it one line above. You could have achieved the same by using defaultMonster as the result.

Related