2013-12-04 5 views
4

Login Jsp форма и яровой безопасности XML-конфигурации выглядит следующим образом:Тестирование Spring Security Controller с помощью Spring MVC тест

<spring:url value="/j_spring_security_check" var="login" /> 
<form action="${login}" method="POST"> 
<fieldset> 
    <legend>Login</legend> 
     <input type="text" name="j_username" id="username" placeholder="Usename"/> 
     <input type="text" name="j_password" id="password" placeholder="Password"/> 
     <input type="submit" value="Login" /> 
</fieldset> 
</form> 
... 
<security:form-login login-page="/public/authentication/login.htm" 
    login-processing-url="/j_spring_security_check" 
    default-target-url="/public/index.htm" 
    authentication-failure-url="/public/authentication/login.htm?authenticationNok=1"/> 

Вот тест для формы sumbission:

@Test 
public void testLoginPostController() throws Exception { 
    Account account = new AccountBuilder("test", "test", "[email protected]", Address.FAKE_EMPTY_ADDRESS4TESTS) 
      .build(); 
    this.mockMvc.perform(post("/j_spring_security_check").param("j_username", account.getUsername()).param("j_password", "test")) 
      .andDo(print()) 
      .andExpect(status().isMovedTemporarily()) 
      .andExpect(view().name("redirect:/public/index.htm")); 
} 

Но я получаю: java.lang.AssertionError: Status expected:<302> but was:<404>

Когда я открываю страницу входа в браузере я вижу, что генерируемая форма:

<form action="/SpringMvcExample/j_spring_security_check" method="POST"> 

Хорошо, я попытался изменить тест:

this.mockMvc.perform(post("/SpringMvcExample/j_spring_security_check").param("j_username", account.getUsername()).param("j_password", "test")) 

Но получил тот же результат. В то же время, когда я отправляю форму входа в браузер, она перенаправляет меня на страницу public/index.htm, как exptect в тесте.

Что я делаю неправильно?

ответ

7

ОБНОВЛЕНИЕ: Spring Security 4 добавила официальное сообщение Test Support. Существует раздел, который подробно описывает testing with MockMvc.

Звучит так, как будто вы не добавили фильтр безопасности Spring в свой MockMvc. Например:

public class MyTests { 

    @Autowired 
    private FilterChainProxy springSecurityFilterChain; 

    @Autowired 
    private WebApplicationContext wac; 

    private MockMvc mockMvc; 

    @Before 
    public void setup() { 
     this.mockMvc = MockMvcBuilders.webApplicationContextSetup(this.wac) 
      .addFilters(this.springSecurityFilterChain).build(); 
    } 

    @Test 
    public void testLoginPostController() throws Exception { 
     Account account = new AccountBuilder("test", "test", "[email protected]", Address.FAKE_EMPTY_ADDRESS4TESTS) 
       .build(); 
     this.mockMvc.perform(post("/j_spring_security_check").param("j_username", account.getUsername()).param("j_password", "test")) 
       .andDo(print()) 
       .andExpect(status().isMovedTemporarily()) 
       .andExpect(view().name("redirect:/public/index.htm")); 
    } 

} 

Причина это происходит потому, что прямо сейчас MockMvc знает только конфигурации Spring MVC и не знает о какой-либо фильтр (то есть в FilterChainProxy). Поскольку проверка имени пользователя и пароля (т. Е. Обработка/j_spring_security_check) происходит в FilterChainProxy до его отправки в Spring MVC, и вы не включили его, вы получаете 404.

0

/j_spring_security_check - особый адрес, которым управляет Spring Security (возможно, через его фильтр, но я этого не подтвердил). Это не обработчик запросов, зарегистрированный в Spring MVC, поэтому вы не можете использовать MockMVC для его проверки.

Вам необходимо запустить настоящий контейнер приложения и использовать что-то HttpClient или Selenium.

Смежные вопросы