2017-10-11 15 views
0

我试图在我的Spring Boot端点上运行测试,该端口应接受来自客户端form的信息,将输入字段映射到DTO并将其保存到数据库中,但我无法让测试模式接受它。从我的理解,当你有一个控制器端点定义是这样的:嘲笑JSON数据发送到Spring Boot测试 - 自动绑定到@ModelAttribute

@PostMapping(path = "/newContact") 
public @ResponseBody ContactDTO createNewContact(
     @ModelAttribute ContactDTO newContact) { 
    //persists newContact to the data tier 
} 

的@ModelAttribute标签会自动搜索newContact DTO的传入的JSON名称字段的名称,然后映射的JSON值填补DTO的领域。

这里是我ContactDTO类:

public class ContactDTO { 

    private BigInteger userId; 
    private BigInteger contactId; 
    private String name; 
    private String email; 
    private String bday; 
    private String address; 
    private String city; 
    private String state; 
    private List<PhoneDTO> phones; 
    private MultipartFile contactImgUpload; 

    //getters and setters 

} 

首先,这是一个正确的认识?

所以,我想测试我的终点作品,通过使预期的DTO,但它转换成JSON,然后张贴的JSON控制器端点:

@Autowired 
    ObjectMapper objectMapper; 

    @Test 
    public void saveAnEntryWhenPOSTUserWithMultiplePhones() throws Exception { 
    List<PhoneDTO> phones = new ArrayList<>(); 
    phones.add(new PhoneDTO("landline", "12312312312")); 
    phones.add(new PhoneDTO("mobile", "3242523462")); 

    ContactDTO cDTO = new ContactDTO(); 
    cDTO.setContactId(BigInteger.valueOf(555)); 
    cDTO.setName("Multiphone User"); 
    cDTO.setUserId(BigInteger.valueOf(123)); 
    cDTO.setEmail("[email protected]"); 
    cDTO.setBday("01/01/1987"); 
    cDTO.setState("IL"); 
    cDTO.setCity("Chicago"); 
    cDTO.setAddress("55 Jackson"); 
    cDTO.setPhones(phones); 

    this.mockMvc.perform(post("/newContact") 
      .contentType(MediaType.APPLICATION_JSON) 
      .content(objectMapper.writeValueAsString(cDTO))) 
      .andExpect(status().isOk()) 
      .andExpect(content().string(containsString("\"phoneType\":\"landline:\""))); 
    } 

但是当我做这显然不是以预期的方式发送JSON,因为它试图保存到数据层时失败,说预计将填充的一些预期字段(这里是“名称”字段)是空的:

org.springframework.web.util.NestedServletException: Request processing failed; 
nested exception is javax.validation.ConstraintViolationException: 
Validation failed for classes [app.models.relationentities.Contact] during 
persist time for groups [javax.validation.groups.Default, ] 

    List of constraint violations:[ 

     ConstraintViolationImpl{interpolatedMessage='may not be null', 
propertyPath=name, rootBeanClass=class app.models.relationentities.Contact, messageTemplate='{javax.validation.constraints.NotNull.message}'} 
    ] 

那么,我错了吗?我如何模拟发送填好的表单到测试中?

编辑 包括phoneDTO,这是什么ContactDTO场private List<PhoneDTO> phones;持有的列表:

public class PhoneDTO { 

    private String phoneType; 
    private String number; 
    //getters and setters 
} 
+0

AFAIK'@ ModelAttribute'用于表单编码数据而非JSON。所以'.param(“contactId”,“155”).param(“foo”,“”)''等 – 2017-10-11 16:23:12

+0

嗯..好吧,那么我将如何包含一个手机列表来填写'ContactDTO's'电话列表,这是上面包含的'PhoneDTO'列表?举个例子,当我为一个ContactDTO发出一个GET请求时,它会像这样回来:'{“userId”:60606,“contactId”:1,“name”:“Nate LastName”,“email”:“nate @ user.com“,”bday“:”01 06 1987“,”address“:”123 Faker Street“,”city“:”Chicago“,”state“:”IL“,”phones“:[{”phoneType“ :“landline”,“number”:“111456666”},{“phoneType”:“mobile”,“number”:“1114567890”}],“contactImgUpload”:null,“base64ImageString”:null}' – NateH06

+0

检查此https ://stackoverflow.com/a/33434317/180100例如 – 2017-10-11 18:13:47

回答

0

使用flashAttr方法。

this.mockMvc.perform(post("/newContact") 
     .contentType(APPLICATION_JSON) 
     .flashAttr("newContact", cDTO)) 
     .andExpect(status().isOk()) 
     ... 

您还可以在控制器和测试不同的URL:/newContact/users/相应。

+0

啊,'/用户'是一个错字,修复它,谢谢。 而Spring Boot docs说使用@ModelAttribute来处理表单提交:https://spring.io/guides/gs/handling-form-submission/ – NateH06

+0

@ NateH06找到我的更新 –

+0

嗯,仍然没有这样做, DTO的字段在运行时仍然空白: '请求处理失败;嵌套异常是javax.validation.ConstraintViolationException:对于[javax.validation.groups。]持续时间期间类[app.models.relationentities.Contact]的验证失败。默认,] 限制违规列表:[ \t ConstraintViolationImpl {interpolatedMessage ='可能不为null',propertyPath = name,rootBeanClass = class app.models.relationentities.Contact,messageTemplate ='{javax.validation.constraints.NotNull。 message}'}' – NateH06