如何模拟SecurityContextHolder.getContext()。getAuthentication()。getCredentials()

时间:2019-08-20 09:49:12

标签: junit spring-security mockito

当我尝试嘲笑时 SecurityContextHolder.getContext()。getAuthentication()。getCredentials()以获得用户详细信息的映射,它给出了错误。 有人可以建议完成此工作的最佳方法吗?使用Mockito

2 个答案:

答案 0 :(得分:0)

ThreadLoacal存储在SecurityContextHolder.getContext()内部。在运行测试用例之前,必须使用SecurityContext为当前正在运行的线程创建Authentication并将模拟的SecurityContextHolder.clearContext()设置为等效于login。

在测试用例的最后,您可以使用SecurityContextThreadLoacal中清除 @ExtendWith(MockitoExtension.class) public class TestSecurity { @Mock private Authentication auth; @BeforeEach public void initSecurityContext() { when(auth.getCredentials()).thenReturn("mockedPassword"); SecurityContextHolder.getContext().setAuthentication(auth); } @Test public void test() { //Access getCredentials() which should return the mocked password SecurityContextHolder.getContext().getAuthentication().getCredentials(); } @AfterEach public void clearSecurityContext() { SecurityContextHolder.clearContext(); } } ,这相当于注销。

明智的代码,它看起来像:

Authentication

或者,如果您感兴趣,还可以考虑使用Spring Security Test中的@WithMockUser来模拟Mockito而不是使用relocation error: /.../app/libQt5XcbQpa.so.5: symbol _ZN20QPlatformIntegration11screenAddedEP15QPlatformScreenb version Qt_5_PRIVATE_API not defined in file libQt5Gui.so.5 with link time reference

答案 1 :(得分:0)

您可以使用建议的@WithMockUserhttps://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#test-method-withmockuser)代替模拟上下文。 如果您想避免嘲笑您的安全性(我更喜欢这样做,因此又写了一个答案),那么可以创建一个登录/注销方法(在您的测试中!更改生产代码以运行测试不是一个好习惯。)可以在测试之前/之后运行,并且实际上将使用保存在数据库中的用户登录到系统。

要执行此操作,您将需要dbunit(http://dbunit.sourceforge.net/)之类的工具来为数据库设置数据(将在您的方案中登录的用户)。 然后,您将需要restTemplate或类似方法来进行登录api的调用,以便登录并保留会话cookie。之后,您可以使用登录工具(在restTemplate的情况下,在系统上进行所有呼叫(这意味着重用restTemplate而不是在测试中创建新的呼叫)和之后完成后,请退出注销api,以便使会话无效并为下一次测试做好准备。这样一来,您的测试就不会因为会话而相互干扰。

希望有帮助!