Test de l'intégration de Spring Spring avec MockMVC
Je vais avoir quelques problèmes de test d'un Printemps de l'application de Démarrage avec MockMvc.
J'ai suivantes de la classe de test:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {SpringConfiguration.class, SecurityConfiguration.class})
@IntegrationTest({"server.port=8080"})
@WebAppConfiguration
public class DemoTest {
@Autowired
private EmbeddedWebApplicationContext webApplicationContext;
private MockMvc mockMvc;
@Before
public void setUp() throws Exception {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
@Test
public void testGetAccountUnauthenticated() throws Exception {
mockMvc.perform(get("/accounts/1").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isUnauthorized());
}
}
Il en résulte une HTTP 200 401. J'ai composant de numérisation et de configuration automatique activée et le printemps de sécurité est configuré dans mon SecuityConfiguration classe comme suit:
@Configuration
@EnableWebSecurity
@EnableWebMvcSecurity //required for use of @AuthenticationPrincipal in MVC controllers.
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) {
web.debug(true);
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
//set up authentication.
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated();
//set up form login
}
}
Si j'utilise un RestTemplate pour accéder à http://localhost:8080/accounts/1
puis-je obtenir le comportement attendu (HTTP 401).
J'ai vu d'autres exemples (par exemple,Printemps de Démarrage configuration de la sécurité pour les tests) qui suggèrent que je autowire la FilterChainProxy
et ajouter le filtre manuellement à l'aide de la WebApplicationContext.addFilters(filterChainProxy)
méthode. Toutefois, cette réalité ne parvient pas pour moi (org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.security.web.FilterChainProxy] found
).
J'ai deux questions:
- Pourquoi le injecté WebApplicationContext pas utiliser automatiquement le SpringSecurity filtres? Même si je pourrais obtenir le FilterChainProxy et l'ajouter manuellement, la JavaDoc de EmbeddedWebApplicationContext états
tout {@link Servlet} ou {@link Filtre} haricots définis dans le contexte sera enregistré automatiquement intégré à conteneur de Servlet
Comme un résultat, je ne m'attends pas à avoir à ajouter manuellement le filtre de sécurité de la chaîne depuis que j'ai (mal?) attendre à ce que cela "fonctionne" en raison de la Configuration Automatique de la magie dans le Printemps de Démarrage?
- Pourquoi n'est-il pas FilterChainProxy dans le contexte de l'application? Encore une fois, peut-être que mes attentes de la configuration automatique est incorrecte, mais je pensais que ce serait être configurés dans le contexte de configuration.
Merci d'avance pour tous les conseils.
Modifications
- La raison pour laquelle un FilterChainProxy à ne pas avoir injecté était parce que je dispose de mon jeu de configuration pour
public void configurer(WebSecurity web) {
web.debug(true);
}
Ce fait configure un org.springframework.security.web.debug.DebugFilter
à la place. La façon dont j'ai réussi à obtenir le Filtre indépendamment de ce paramètre debug est comme suit:
@Resource(name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)
private Filter securityFilter;
Si j'ajoute à cela le MockMvcBuilder comme suit:
MockMvcBuilders.webAppContextSetup(webApplicationContext).addFilters(securityFilter)
alors il ne fonctionne pas comme prévu.
Mais, je ne comprends pas pourquoi MockMVC serait ignorer les filtres comme cela semble important pour l'essai d'une demande depuis quelque chose pourrait se produire dans un Filtre qui pourrait avoir une incidence sur le résultat du test. En outre, il signifie que pour tester correctement j'avais besoin pour la recherche de tous les Filtres dans le contexte de servlet et établir leur ordre de priorité/mappage d'url et de les ajouter de façon appropriée. Cela semble sujette aux erreurs et inutile.
source d'informationauteur David Goate
Vous devez vous connecter pour publier un commentaire.
Je suis d'accord que se Moquer deMVC est peut-être plus pour les tests de PrintempsMVC et du code personnalisé dans les contrôleurs, comme indiqué par @dave-syer. Donc, dans les cas où l'on veut tester spring MVC de l'infrastructure de votre propre code de contrôleur en même temps (la justesse de contrôleurs mappés vers des Url; la cartographie et la validation de l'entrée et la sortie des objets; contrôleurs standard; vos contrôleurs) sans effet de levier le conteneur de Servlet partie de la pile, MockMVC est là pour vous.
Mais MockMVC fait aussi ont des méthodes pour ajouter des filtres, de sorte qu'il est conçu avec une possibilité d'engager des Filtres dans la décrit le type de test. Parfois filtre peuvent jouer un rôle fonctionnel pour le code à l'intérieur d'un contrôleur et qui serait autrement pas testable avec MockMVC.
Avec toute cette théorie dans la tête, j'essayais d'imiter le comportement de Démarrage pour mes tests où les filtres serait mis en place au Printemps de Démarrage chemin et repris par mes essais pour être utilisé avec MockVMC. Voici un extrait de code que j'ai utilisé. Il peut certainement être améliorée afin d'imiter le comportement de Démarrage en plus de précision et en extrait de coutume, MockMVCBuilder.