单元测试@PreAuthorized(hasRole)控制器方法

时间:2014-01-16 09:24:50

标签: spring unit-testing authentication spring-security

我正在尝试为此控制器方法编写单元测试

    @PreAuthorize("hasRole(#d.code) or hasRole('ROLE_ALL_ACCESS')")
@RequestMapping(value = "{department}/{examination}", method = RequestMethod.GET)
public String show(ModelMap model, Principal principal, Locale locale, D d) {
    model.addAttribute(service.getItem(d) //THIS CAUSES NULL ON TEST
            .addAttribute(new DateTime())
            .addAttribute(locale);
    return "show"; 

我试过这个

@Test (expected=AccessDeniedException.class)
public void testShowAccessDenied() {
super.simulateRole("ROLE_STUDENT");
 controller.show(new ModelMap(), Helper.getTestPrincipal(), Locale.getDefault(), new D());

但它会在标记的行上导致NullPointerException,这意味着test正在运行该方法,而不是基于错误的角色抛出AccessDeniedException。

我的超级测试班是

 public class AuthorizeTestBase {

private Mockery jmock = new JUnit4Mockery();
private AuthenticationManager authenticationManager= jmock.mock(AuthenticationManager.class);

@Before
public void setUp() {
 jmock.checking(new Expectations() {{ ignoring(anything()); }});   
}

protected void simulateRole(String role) {
    List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
    authorities.add(new SimpleGrantedAuthority(role));
    PreAuthenticatedAuthenticationToken pat = new PreAuthenticatedAuthenticationToken(Helper.getTestPrincipal(), "", authorities);
    SecurityContextHolder.getContext().setAuthentication(authenticationManager.authenticate(pat));

}

Helper.getTestPrincipal是

 LdapPerson.Essence essence = new LdapPerson.Essence();
 LdapPerson user = (LdapPerson) essence.createUserDetails(); 
 return new PreAuthenticatedAuthenticationToken(user, "password");

我认为我在模拟authenticationManager时遗漏了一些东西。救救我!

1 个答案:

答案 0 :(得分:0)

当您尝试拨打服务时,NPE正在发生。你的类AuthorizeTestBase不知道任何spring beans service / dao等。所以应该加载弹簧丝配置。以下是一个例子。

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(locations = {"classpath:/applicationContext-test.xml",
                                   "classpath:/applicationContext-ABC-test.xml",
                                   "classpath:/applicationContext-DEF-test.xml",
                                   "classpath:/applicationContext-serviceGHI-test.xml",
                                   "classpath:/applicationContext-securityHIJ-test.xml"
})
 public class AuthorizeTestBase {
.....

}

另请查看 - Spring MVC Test Framework