2017-10-11 1 views
0

Ich versuche, einen Test auf meinem Spring Boot-Endpunkt, der Informationen von einem Client-Seite form übernehmen akzeptiert, um die Eingabefelder zuordnen das DTO und hält es in der DB, aber ich kann das Testschema nicht erhalten, um es zu akzeptieren. Von meinem Verständnis, wenn Sie einen Controller Endpunkt wie folgt definiert haben:Mocking JSON-Daten zu Spring Test senden - autobind zu @ModelAttribute

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

der @ModelAttribute Tag wird für den Namen der Felder des newContact DTO im eingehenden JSON Namen automatisch sucht und dann die json Werte abbilden um die Felder des DTO zu füllen.

Hier ist meine ContactDTO Klasse:

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 

} 

Zum einen ist dies ein korrektes Verständnis?

Also, ich versuche, dass mein Endpunkt Arbeiten zu testen, um die erwartete DTO zu machen, aber es zu JSON konvertieren und dann POSTen dass JSON an den Controller Endpunkt:

@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:\""))); 
    } 

Aber wenn ich tun Dies führt dazu, dass das JSON offensichtlich nicht in der erwarteten Weise gesendet wird, da es fehlschlägt, wenn versucht wird, in die Datenebene zu speichern. Einige der erwarteten Felder, die ausgefüllt werden sollen (hier das Feld "name"), sind leer :

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}'} 
    ] 

Also bin ich falsch mit dem Test? Wie stelle ich das Senden eines ausgefüllten Formulars zum Test falsch dar?

bearbeiten Einschließlich der phoneDTO, das, was das ContactDTO Feld ist private List<PhoneDTO> phones; eine Liste gilt:

Methode
public class PhoneDTO { 

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

AFAIK '@ ModelAttribute' ist für formcodierte Daten nicht JSON. Also '.param (" contactId "," 155 "). Param (" foo "," ")' usw. –

+0

Hmm .. ok, wie würde ich dann eine Liste von Telefonen hinzufügen, um die 'ContactDTO'-Liste von Telefonen auszufüllen , welches ist eine Liste der oben angegebenen 'PhoneDTO'? Wenn ich zum Beispiel eine GET-Anfrage für ein ContactDTO mache, kommt es so zurück: '{" userId ": 60606," contactId ": 1," name ":" Nate Nachname "," email ":" nate @ user.com "," bday ":" 01 06 1987 "," Adresse ":" 123 Faker Street "," Stadt ":" Chicago "," Staat ":" IL "," Telefone ": [{" phoneType " : "Festnetz", "Nummer": "111456666"}, {"phoneType": "mobile", "Nummer": "1114567890"}], "contactImgUpload": null, "base64ImageString": null} ' – NateH06

+0

überprüfen Sie diese https : //stackoverflow.com/a/33434317/180100 zum Beispiel –

Antwort

0

Verwendung flashAttr.

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

Sie haben auch verschiedene URLs in der Steuerung und deren Test: /newContact und /users/ entsprechend.

+0

Ah, die '/ Benutzer' war ein Tippfehler, behoben, danke. Und die Spring-Boot-Dokumente sagen, um die Übermittlung des Formulars mit @ModelAttribute umgehen: https://spring.io/guides/gs/handling-form-submission/ – NateH06

+0

@ NateH06 finden Sie mein Update –

+0

Hmm, immer noch nicht dabei, die Felder des DTO werden immer noch leer angezeigt, wenn es ausgeführt wird: 'Anfrage Verarbeitung fehlgeschlagen; Die verschachtelte Ausnahme ist javax.validation.ConstraintViolationException: Die Validierung für Klassen [app.models.relationsities.Contact] ist während der persistenten Zeit für Gruppen [javax.validation.groups fehlgeschlagen.Liste der Einschränkungsverletzungen: [ \t ConstraintViolationImpl {interpolatedMessage = 'darf nicht null sein', propertyPath = name, rootBeanClass = Klasse app.models.relationstitties.Contact, messageTemplate = '{javax.validation.constraints.NotNull. message} '} ' – NateH06

Verwandte Themen