调用 Spring SecurityContextHolder 时的 NullPointerException



我一直在尝试为以下代码行编写一个测试用例,但我不断得到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 - 问题 61。

您必须以不同的方式设计代码/测试。例如,将一个"user"主体传递给你的方法参数,并使 Authentication.getPrincipal() 返回另一个(它们会不同,从而使等号返回 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();
 
 

    }

相关内容

  • 没有找到相关文章

最新更新