【问题标题】:Spring Boot rest controller testSpring Boot 休息控制器测试
【发布时间】:2019-04-02 16:40:28
【问题描述】:

我正在为我的控制器编写测试,并且已经能够找到搜索端点。我现在尝试插入,但没有成功。

我的服务:

public LegalPerson insert(LegalPerson legalPerson) {
        legalPerson.setId(null);
        try {
            legalPerson = repository.save(legalPerson);
        } catch (DataIntegrityViolationException error) {
            throw new DataIntegrity("Error something***", error);
        }
        return legalPerson;
    }

 public LegalPerson modelToEntity(LegalPersonModel personModel) {
        return LegalPerson.builder()
                .active(personModel.getActive())
                .companyId(personModel.getCompanyId())
                .tradeName(personModel.getTradeName())
                .companyName(personModel.getCompanyName())
                .email(personModel.getEmail())
                .cnpj(personModel.getCnpj())
                .stateRegistration(personModel.getStateRegistration())
                .municipalRegistration(personModel.getMunicipalRegistration())
                .openingDate(personModel.getOpeningDate())
                .address(personModel.getAddress())
                .companyType(personModel.getCompanyType())
                .subsidiaries(personModel.getSubsidiaries())
                .phones(personModel.getPhones())
                .build();
    }

我的休息控制器

@RestController
@RequestMapping(value = "/api/clients/lp")
public class LegalPersonResource {

/**other methods ***/
 @PostMapping
    public ResponseEntity<Void> insert(@Valid @RequestBody LegalPersonModel legalPersonModel) {
        var legalPerson = service.modelToEntity(legalPersonModel);
        legalPerson = service.insert(legalPerson);
        return ResponseEntity.created(ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}")
                .buildAndExpand(legalPerson.getId()).toUri()).build();
    }

还有我的测试

@Test
void insert() throws Exception {
 var mockLPM = new LegalPersonModel(true, 1L, "mockTrade", "mockCompanyName", "mockTest@com", "63.236.885/0001-42", "123455", "1234566", localDate, 1L, CompanyEnum.HEADOFFICE,subsidiaries, phones);
   var objason = new ObjectMapper();
   objason.writeValueAsString(mockLPM);
   var test = mvc.perform(MockMvcRequestBuilders.post("/api/clients/lp").contentType(MediaType.APPLICATION_JSON_UTF8_VALUE).content(String.valueOf(objason))).andReturn();

 int status = test.getResponse().getStatus();
 Assertions.assertEquals(201, status);
}

总是返回状态 400。 我做错了什么?

==== 更新:====

它在部分工作。

它只适用于 ObjectMapper,我必须将 LocalDate 更改为 null,因为它会将 localDate 转换为一个巨大的字符串:

"openingDate": {"year": 1955, "month": "OCTOBER", "monthValue": 10, "dayOfMonth": 25, "chronology": {"calendarType": "iso8601", "id" "}," era ":" CE "," dayOfYear ": 298," dayOfWeek ":" TUESDAY "," leapYear ": false}

实际上我的 json 应该是这样的: "openingDate": "2019-04-02" 例如。

因此,当我将 localDate 更改为 null 时,它会通过该部分,但在我的服务的该部分中会出现 NullPointerException:

var legalPerson = service.modelToEntity (legalPersonModel);

它可以识别legalPersonModel,这是我们刚刚通过ObjectMapper 传递的,但是legalPerson 始终保持为null,它没有被转换。

我尝试了一些没有成功的事情。我该怎么办?

=== 更新 2 ===

如果在其余控制器中,有:

 return ResponseEntity.created (ServletUriComponentsBuilder.fromCurrentRequest (). path ("/ {id}")
                .buildAndExpand (legalPerson.getId ()). toUri ()). build ();

将返回 null。

但如果我切换到

return ResponseEntity.status (201) .build ();

我有一个绿色测试。

有没有办法解决这个问题?

【问题讨论】:

    标签: spring-boot mockito junit5


    【解决方案1】:

    只要您posting 的有效负载不是有效类型,您就会获得400 Bad Request 状态 - 在您的示例中,您应该post 一个可以反序列化为LegalPersonModel 对象的有效负载。

    您可以将有效负载直接作为json 字符串发布

    @Test
    void insertAsJsonString() throws Exception {
        var mockLPM = new LegalPersonModel(true,
                1L,
                "mockTrade",
                "mockCompanyName",
                "mockTest@com",
                "63.236.885/0001-42",
                "123455",
                "1234566",
                localDate,
                1L,
                CompanyEnum.HEADOFFICE,
                subsidiaries,
                phones);
    
        var om = new ObjectMapper();
    
        var test = mvc.perform(
                MockMvcRequestBuilders
                        .post("/api/clients/lp")
                        .contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)
                        .content(om.writeValueAsString(mockLPM))
                .andReturn();
    
        int status = test.getResponse().getStatus();
        Assertions.assertEquals(201, status);
    }
    

    要将LocalDate序列化为yyyy-MM-dd格式,请尝试像这样配置ObjectMapper

    ObjectMapper om = new ObjectMapper();
    om.registerModule(new JavaTimeModule());
    om.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
    

    您可能需要导入jackson-datatype-jsr310。使用maven 像这样导入它

    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-jsr310</artifactId>
        <version>2.9.8</version>
    </dependency>
    

    如果var legalPerson = service.modelToEntity (legalPersonModel); 始终导致legalPerson 为null,即使LocalDate 被正确序列化,您也需要使用LegalPerson 类更新问题,包括builder 模式。


    我无法重现“更新 2”问题。

    鉴于这个终点

    @PostMapping
    public ResponseEntity<Void> insert(@Valid @RequestBody LegalPersonModel legalPersonModel) {
        var legalPerson = service.modelToEntity(legalPersonModel);
        legalPerson = service.insert(legalPerson);
        return ResponseEntity.created(ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}")
                .buildAndExpand(legalPerson.getId()).toUri()).build();
    }
    

    将返回以下内容(使用命令行工具curl)

    $ curl -X POST -d @legalPersonModelMock 'http://localhost:8080/api/clients/lp'
    < HTTP/1.1 201 
    < Location: http://localhost:8080/api/clients/lp/1
    < Content-Length: 0
    

    legalPersonModelMock 文件的内容是json 的var mockLPM = new LegalPersonModel(...) 表示。

    您的service.insert(...) 代码设置为legalPerson.setId(null);,您确定这不会影响响应吗?

    【讨论】:

    • 更新了试图解决更新问题的答案
    • 更新答案。
    猜你喜欢
    • 2019-03-27
    • 2018-07-31
    • 2018-11-23
    • 2019-02-01
    • 2018-07-31
    • 2018-10-17
    • 1970-01-01
    • 2018-01-02
    • 2021-05-19
    相关资源
    最近更新 更多