2016-04-21 2 views
3

У меня есть приложение Spring, и я строю JUnit тестов для тестирования определенного Controller.Испытайте пружинный контроллер с JUnit, который зависит от весенней безопасности

Проблема заключается в том, что внутри Controller я называю этот код:

final Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); 
final String userName = authentication.getName(); 

Другими словами, мне нужно проверить подлинность перед вызовом этой Controller. Я написал тест JUnit с этим кодом:

private MockMvc mockMvc; 

    @Test 
    public void getPageTest() throws Exception{ 
     final ProcessFileController controller = new ProcessFileController(); 
     mockMvc = standaloneSetup(controller).build(); 

    mockMvc.perform(get(URI.create("/processFile.html")).sessionAttr("freeTrialEmailAddress", "")).andExpect(view().name("processFile")); 
     } 

И когда я бегу он дает мне NullPointerException прямо на final String userName = authentication.getName();, потому что мой authentication является null, так как я не вошёл.

Вопрос: Есть ли способ издеваться над аутентификацией? Все идеи приветствуются.

спасибо.

+1

Почему вы делаете это вручную, вместо того, чтобы использовать '@ AuthenticationPrincipal'? – chrylis

+0

chrylis, архитектура не была разработана для использования '@ AuthenticationPrincipal', мне нужна идея, способ справиться с этим с текущей архитектурой, которую я имею прямо сейчас. Спасибо за ваш ответ. –

ответ

3

В идеале вы бы использовали @AuthenticationPrincipal, но если это не вариант, вам необходимо установить SecurityContext с экземпляром Authentication, который затем будет доступен в тесте.

Вы можете использовать статический метод для вспомогательного класса.

public static void setupSecurityContext(String username, String password, String... groups) 
{ 
    List<GrantedAuthority> authorities = new ArrayList<>(); 
    for (String group : groups) 
    { 
    authorities.add(new SimpleGrantedAuthority(group)); 
    } 

    UserDetails user = new UserDetails(username, password, authorities); 
    UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(user, password); 
    SecurityContextHolder.getContext().setAuthentication(token); 
} 

Тогда в тесте вы можете просто позвонить

SecurityHelper.setupSecurityContext("user", "password", "g1", "g2");

5

Spring Security версия 4 представила некоторые опрятные улучшения относительно этого.

Сначала убедитесь, что у вас есть система тестирования в пути к классам для испытаний, с Maven это выглядит следующим образом:

<dependency> 
    <groupId>org.springframework.security</groupId> 
    <artifactId>spring-security-test</artifactId> 
    <version>4.0.4.RELEASE</version> 
    <scope>test</scope> 
</dependency> 

Полезного импорт: настройка

import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.*; 
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*; 

Теста:

mockMvc = webAppContextSetup(applicationContext).apply(springSecurity()).build(); 

(Я думаю, что вам нужен WebApplicationContext, а не один контроллер.)

Тогда тест что-то вроде:

mockMvc.perform(get(...).with(user("username").roles("USER"))).andExpect(...);