繁体   English   中英

调用Spring SecurityContextHolder时发生NullPointerException

[英]NullPointerException when Spring SecurityContextHolder is called

我一直在尝试为下面的代码行编写一个测试用例,但是我一直在获取java.lang.NullPointerException,我一直在尝试遵循/复制其他人在这里提出的使用Spring Security进行单元测试的建议但是我没有运气。 有人可以帮助我更好地识别或给我提示我需要做什么。 (我为此使用了Mockito)

码:

if (SecurityContextHolder.getContext().getAuthentication().getPrincipal().equals(user)) {
                continue;
            }

测试用例:

@Test
public void testExpireAllSession() throws Exception {

        SecurityContext securityContext = Mockito.mock(SecurityContext.class);
        Mockito.when(securityContext.getAuthentication().getPrincipal().equals(any(Object.class))).thenReturn(false);
        SecurityContextHolder.setContext(securityContext);

       controller.theMEthodUnderTest();
}

..

您的测试有2个问题:

  1. 您必须模拟方法调用的每个“级别”,还应该模拟:

    • SecurityContext.getAuthentication()
    • Authentication.getPrincipal()
    • Principal.equals()
  2. 但是 ,您不能模拟.equals(),请参阅Mockito FAQ-限制Mockito-Issue 61

您必须以不同的方式设计代码/测试。 例如,将“用户”主体传递给您的方法参数,并使Authentication.getPrincipal()返回另一个(它们将有所不同,从而使equals返回false):

public void theMethod(Principal user) {
  ...
  if (SecurityContextHolder.getContext().getAuthentication().getPrincipal().equals(user)) {
    continue;
  }
  ...
}

测试

@Test public void testController() {
    SecurityContext securityContext = Mockito.mock(SecurityContext.class);
    Authentication authentication = Mockito.mock(Authentication.class);
    Principal principal1 = Mockito.mock(Principal.class);
    Principal principal2 = Mockito.mock(Principal.class);
    Mockito.when(authentication.getPrincipal()).thenReturn(principal1);
    Mockito.when(securityContext.getAuthentication()).thenReturn(authentication);
    SecurityContextHolder.setContext(securityContext);
    new Controller().theMethod(principal2);
}

我为完成这项工作所做的一些重要工作,希望对其他人也有所帮助。

  1. 使用@InjectMocks:
     @InjectMocks private static YourMainController controller; 
  2. 模拟将添加到上面的主要模拟中的依赖项:
     
    @Mock SecurityContext securityContextMocked; @Mock Authentication authenticationMocked; @Mock Principal principal1;
  3. 修改了测试,使其看起来像这样,并使其正常工作。
     @Test public void testExpireAllSession() throws Exception { List mySessions = new ArrayList<>(); Object principal=""; 
    Date aDate = new Date();
    SessionInformation sessionInformation = new SessionInformation(principal,”100000”,aDate); mySessions.add(sessionInformation); allUsers.add("Mike"); when(authenticationMocked.getPrincipal()).thenReturn(principal1); when(securityContextMocked.getAuthentication()).thenReturn(authenticationMocked); SecurityContextHolder.setContext(securityContextMocked); when(sessionRegistryMocked.getAllSessions(allUsers,false)).thenReturn(sessions); when(sessionRegistryMocked.getAllPrincipals()).thenReturn(allUsers); controller.expireAllSession(); verify(sessionRegistryMocked).getAllPrincipals();
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM