Spring MockMVC, Spring security et Mockito

j'aimerais tester un Spring Boot contrôle de repos, qui est sécurisé par Spring security, et utilisez des moqueries à l'intérieur. J'ai essayé avec Mockito, mais je pense que n'importe quel outil de moquerie devrait faire l'affaire.

pour activer la sécurité de printemps dans mes tests, j'ai d'abord fait ce qui suit:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Main.class)
@TestPropertySource(value="classpath:application-test.properties")
@WebAppConfiguration
@ContextConfiguration
public class MyTest{

    protected MockMvc mockMvc;

    @Autowired
    private WebApplicationContext wac;

    @Before
    public void setUp(){
        mockMvc = MockMvcBuilders
                .webAppContextSetup(wac)
                .apply(SecurityMockMvcConfigurers.springSecurity())
                .build();
    }

    @Test
    public void doTheTest(){
        mockMvc.perform(post("/user/register")
            .with(SecurityMockMvcRequestPostProcessors.csrf())
            .content(someContent()));
    }
}

Jusqu'à là, ça marche bien.

après cette étape, j'ai voulu ajouter des mocks pour tester mon contrôleur sécurisé en isolation.

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Main.class)
@TestPropertySource(value="classpath:application-test.properties")
@WebAppConfiguration
@ContextConfiguration
public class MyTest{

    protected MockMvc mockMvc;

    @Mock
    private Myservice serviceInjectedInController;

    @InjectMocks
    private MyController myController;

    @Autowired
    private WebApplicationContext wac;

    @Before
    public void setUp(){
        mockMvc = MockMvcBuilders
                .webAppContextSetup(wac)
                .apply(SecurityMockMvcConfigurers.springSecurity())
                .build();
    }

    @Test
    public void doTheTest(){
        mockMvc.perform(post("/user/register")
            .with(SecurityMockMvcRequestPostProcessors.csrf())
            .content(someContent()));
    }
}

malheureusement, le service moqué n'est pas injecté dans le régulateur, car il n'y a aucun rapport entre la MockMVC et les Mocks, de sorte que les mocks ne sont pas injectés dans le régulateur.

alors j'ai essayé de changer la configuration du MockMVC, comme suit:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Main.class)
@TestPropertySource(value="classpath:application-test.properties")
@WebAppConfiguration
@ContextConfiguration
public class MyTest{

    protected MockMvc mockMvc;

    @Mock
    private Myservice serviceInjectedInController;

    @InjectMocks
    private MyController myController;


    @Before
    public void setUp(){
        mockMvc = MockMvcBuilders
                .standAloneSetup(myController)
                .apply(SecurityMockMvcConfigurers.springSecurity())
                .build();
    }

    @Test
    public void doTheTest(){
        mockMvc.perform(post("/user/register")
            .with(SecurityMockMvcRequestPostProcessors.csrf())
            .content(someContent()));
    }
}

Mais dans ce cas, j'ai une autre question. Spring security se plaint de la configuration:

java.lang.IllegalStateException: springSecurityFilterChain cannot be null. Ensure a Bean with the name springSecurityFilterChain implementing Filter is present or inject the Filter to be used.

Je n'ai pas d'autre idée pour faire la sécurité et se moquer. Une idée? Ou dois-je faire d'une autre manière?

Merci.

9
demandé sur Rémi Doolaeghe 2015-11-04 17:33:41

1 réponses

par défaut l'intégration recherche un haricot avec le nom de "springSecurityFilterChain". Dans l'exemple fourni, une configuration autonome est utilisée, ce qui signifie MockMvc ne seront pas au courant de l' WebApplicationContext et donc ne pas pouvoir rechercher la fève" springSecurityFilterChain".

la façon la plus simple de résoudre ceci est d'utiliser quelque chose comme ceci:

    MockMvc mockMvc = MockMvcBuilders
            // replace standaloneSetup with line below
            .webAppContextSetup(wac)
            .alwaysDo(print())
            .apply(SecurityMockMvcConfigurers.springSecurity())
            .build();

Si vous voulez vraiment utiliser un standaloneSetup (n'a pas vraiment de sens puisque vous avez déjà un Contextwebapplicationcon), vous pouvez explicitement fournir le champ springSecurityFilterChain en utilisant:

@Autowired
FilterChainProxy springSecurityFilterChain;

@Before
public void startMocks(){
    controller = wac.getBean(RecipesController.class);

    MockMvc mockMvc = MockMvcBuilders
            .standaloneSetup(controller)
            .alwaysDo(print())
            .apply(SecurityMockMvcConfigurers.springSecurity(springSecurityFilterChain))
            .build();

    MockitoAnnotations.initMocks(this);
}
10
répondu Rob Winch 2015-12-16 16:14:16