Test d'intégration de l'Affichage d'un objet entier de contrôleur Spring MVC
Est-il un moyen de passer un ensemble de la forme de l'objet à se moquer de la demande lors des tests d'intégration d'un spring mvc web app? Tout ce que je peux trouver est de passer chaque domaine séparément comme un paramètre comme ceci:
mockMvc.perform(post("/somehwere/new").param("items[0].value","value"));
Ce qui est bien pour les petites formes. Mais que faire si ma posté objet est importante, plus? Il fait également le code de test look plus agréable si je peux juste poster un objet entier.
Plus précisément je voudrais tester la sélection de plusieurs éléments par case, puis de les afficher. Bien sûr, j'ai pu tester la qualité de l'enregistrement d'un seul élément, mais je me demandais..
Nous sommes à l'aide de printemps 3.2.2 avec le printemps-test-mvc inclus.
Mon Modèle pour la forme ressemble à quelque chose comme ceci:
NewObject {
List<Item> selection;
}
J'ai essayé appelle comme ceci:
mockMvc.perform(post("/somehwere/new").requestAttr("newObject", newObject)
à un Contrôleur comme ceci:
@Controller
@RequestMapping(value = "/somewhere/new")
public class SomewhereController {
@RequestMapping(method = RequestMethod.POST)
public String post(
@ModelAttribute("newObject") NewObject newObject) {
//...
}
Mais l'objet sera vide (oui, j'ai rempli avant dans le test)
La seule solution que j'ai trouvé était à l'aide de @SessionAttribute comme ceci:
Des Tests d'intégration de Spring MVC Applications: les Formes
Mais je n'aime pas l'idée d'avoir à penser à appeler à la fin de chaque contrôleur où j'ai besoin de cela. Après toutes les données du formulaire ne doit pas être à l'intérieur de la session, j'ai seulement besoin pour la demande.
Donc la seule chose à laquelle je pense est de faire écrire quelques Util classe qui utilise la MockHttpServletRequestBuilder pour ajouter tous les champs d'objet comme .param à l'aide de réflexions ou individuellement pour chaque cas de test..
Je ne sais pas, feeld de l'onu-intuitif..
Des pensées et des idées sur comment je pourrais faire de ma vie plus facile? (En dehors de tout appeler le contrôleur directement)
Merci!
- essayez d'utiliser gson et de convertir l'objet en json et le poster ??
- comment va l'aider? Mon formulaire de post
MediaType.APPLICATION_FORM_URLENCODED
de données donc mon test doit envoyer des données.. j'ai même essayé de le convertir dans le lien que j'ai postet l'envoi de byte[] pour le contrôleur, mais il ne veut toujours pas le ramasser..
Vous devez vous connecter pour publier un commentaire.
L'un des principaux objectifs des tests d'intégration avec
MockMvc
est de vérifier que les objets de modèle sont correctement renseignés avec les données de formulaire.Pour ce faire, vous devez passer les données d'un formulaire qu'ils sont passés de la forme (à l'aide de
.param()
). Si vous utilisez une conversion automatique deNewObject
à partir des données, le test ne traite pas de classe particulière de problèmes éventuels (modifications deNewObject
incompatible avec la forme réelle).J'ai eu la même question et il s'est avéré que la solution était assez simple, en utilisant JSON marshaller.
Avoir votre manette, il suffit de changer la signature par l'évolution de la
@ModelAttribute("newObject")
à@RequestBody
. Comme ceci:Ensuite dans vos tests, vous pouvez simplement dire:
Où la
asJsonString
méthode est juste:import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
. J'ai mis à jour ma réponse.Je crois que j'ai le plus simple encore de réponse à l'aide de Spring Boot 1.4, inclus dans les importations de la classe de test.:
Je pense que la plupart de ces solutions sont loin d'être trop compliqué.
Je suppose que dans votre contrôleur de test vous avez cette
Si ses un service rest
Pour spring mvc à l'aide d'une forme validée je suis venu avec cette solution. (Pas vraiment sûr si c'est une bonne idée encore)
L'idée de base est de
- d'abord le convertir en objet à la chaîne json pour obtenir tous les noms de champ facilement
- convertir cette chaîne json dans une carte et de la déverser dans un
MultiValueMap
que le printemps s'attend. Éventuellement filtrer les champs que vous ne voulez pas inclure (Ou vous pouvez annoter les champs avec@JsonIgnore
pour éviter cette étape supplémentaire)Une autre façon de résoudre la Réflexion, mais sans ordonnancement:
J'ai ce abstraite de la classe helper:
Vous l'utiliser comme ceci:
J'ai déduit qu'il est préférable d'être en mesure de parler de la propriété des chemins lors de la construction de la forme, car j'ai besoin de faire varier que dans mes tests. Par exemple, je pourrais être amené à vérifier si j'obtiens une erreur de validation sur une entrée manquante et je vais quitter le chemin de la propriété pour simuler les conditions. Je trouve aussi qu'il est plus facile de construire mon modèle d'attributs dans un @Avant méthode.
La BeanUtils est de commons-beanutils:
J'ai rencontré le même problème il y a un moment et ne le résoudre à l'aide de la réflexion avec l'aide de quelques Jackson.
D'abord remplir une carte avec tous les champs d'un Objet. Puis ajouter ces entrées de mappage en tant que paramètres de la MockHttpServletRequestBuilder.
De cette façon, vous pouvez utiliser n'importe quel Objet et vous êtes de passage comme les paramètres de la demande. Je suis sûr qu'il y a d'autres solutions mais celle-ci a travaillé pour nous:
Voici la méthode que j'ai faite pour transformer de manière récursive les champs d'un objet dans une carte prête à être utilisée avec un
MockHttpServletRequestBuilder
GenericDTO
est une simple classe étendantSerializable
et voici le
ReflectionUtils
classeVous pouvez l'utiliser comme
Je n'ai pas testé beaucoup, mais il semble fonctionner.