[英]Test a Spring Controller with JUnit that depends of Spring Security
I have a Spring Application and I am building JUnit
tests to test a certain Controller
. 我有一个Spring应用程序,我正在构建
JUnit
测试来测试某个Controller
。
The problem is that inside the Controller
I call this code: 问题是在
Controller
我调用这段代码:
final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
final String userName = authentication.getName();
In other words, I need to authenticate before calling this Controller
. 换句话说,我需要在调用此
Controller
之前进行身份验证。 I wrote a JUnit
test with this code: 我用这段代码编写了一个
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"));
}
And when I run it gives me a NullPointerException
right on the final String userName = authentication.getName();
当我运行它时,在
final String userName = authentication.getName();
上给我一个NullPointerException
final String userName = authentication.getName();
because my authentication
is null
since I did not login. 因为我的
authentication
为null
因为我没有登录。
The question is: Is there a way to mock the authentication? 问题是:有没有办法模拟身份验证? All ideas are welcome.
欢迎所有想法。
Thank you. 谢谢。
Spring Security version 4 introduced some neat improvements regarding this. Spring Security版本4对此进行了一些改进。
First make sure you have the testing framework in the classpath for tests, with Maven it looks like: 首先确保你在测试的类路径中有测试框架,Maven看起来像:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<version>4.0.4.RELEASE</version>
<scope>test</scope>
</dependency>
Useful imports: 有用的进口:
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.*;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*;
Test setup: 测试设置:
mockMvc = webAppContextSetup(applicationContext).apply(springSecurity()).build();
(I think you need to the WebApplicationContext rather than a single controller.) (我认为您需要WebApplicationContext而不是单个控制器。)
Then the test something like: 然后测试类似于:
mockMvc.perform(get(...).with(user("username").roles("USER"))).andExpect(...);
Ideally you would use @AuthenticationPrincipal
but if that isn't an option you need to setup the SecurityContext
with an Authentication
instance that will then be available in the test. 理想情况下,您将使用
@AuthenticationPrincipal
但如果这不是一个选项,您需要使用Authentication
实例设置SecurityContext
,然后在测试中可用。
You could you a static method in a helper class to do this. 您可以在辅助类中使用静态方法来执行此操作。
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);
}
Then in the test you can simply call 然后在测试中你可以简单地打电话
SecurityHelper.setupSecurityContext("user", "password", "g1", "g2");
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.