Spring boot 如何模拟Spring启动会话和SecurityContext进行测试
这是SpringBoot项目。它使用SecurityContext 出于验证目的,其大多数Rest控制器和服务都取决于其登录用户的角色。所以在测试期间,我需要一个用户登录 请告诉我单元测试代码示例,用于Spring引导,涉及登录用户过程Spring boot 如何模拟Spring启动会话和SecurityContext进行测试,spring-boot,unit-testing,junit,mockito,Spring Boot,Unit Testing,Junit,Mockito,这是SpringBoot项目。它使用SecurityContext 出于验证目的,其大多数Rest控制器和服务都取决于其登录用户的角色。所以在测试期间,我需要一个用户登录 请告诉我单元测试代码示例,用于Spring引导,涉及登录用户过程 @RunWith(PowerMockRunner.class) @PrepareForTest({SecurityContextHolder.class,AuthenticationManager.class,UserRepository.class,UserC
@RunWith(PowerMockRunner.class)
@PrepareForTest({SecurityContextHolder.class,AuthenticationManager.class,UserRepository.class,UserCreationRequestRepository.class, PasswordEncoder.class,AuthorityRepository.class,CacheManager.class,POMasterCompanyRepository.class,BranchRepository.class})
public class BOAuthControllerTest {
@Autowired
private WebApplicationContext context;
@Mock
private AuthenticationManager authenticationManager;
@Mock
private UserRepository userRepository;
@Mock
private UserCreationRequestRepository userCreationRequestRepository;
@Mock
private PasswordEncoder passwordEncoder;
@Mock
private AuthorityRepository authorityRepository;
@Mock
private CacheManager cacheManager;
@Mock
private POMasterCompanyRepository poMasterCompanyRepository;
@Mock
private BranchRepository branchRepository;
private UserService userService;
private MockMvc mockMvc;
@Before
public void setup() {
userService = new UserService(userRepository, passwordEncoder, authorityRepository, cacheManager, userCreationRequestRepository,
poMasterCompanyRepository,branchRepository);
UsernamePasswordAuthenticationToken authenticationToken =
new UsernamePasswordAuthenticationToken("admin","admin");
Authentication authentication = this.authenticationManager.authenticate(authenticationToken);
SecurityContextHolder.getContext().setAuthentication(authentication);
SecurityContext securityContext = new SecurityContextImpl();
securityContext.setAuthentication(authentication);
System.out.println(authenticationToken==null?"null":"not null");
System.out.println(authenticationManager==null?"null":"not null");
System.out.println(authentication==null?"null":"not null");
System.out.println(SecurityContextHolder.getContext()==null?"null":"not null");
System.out.println(SecurityContextHolder.getContext().getAuthentication()==null?"null":"not null");
System.out.println(SecurityContextHolder.getContext().getAuthentication().getName());
System.out.println(securityContext.getAuthentication().getName());
PowerMockito.mockStatic(SecurityContextHolder.class);
when(SecurityContextHolder.getContext()).thenReturn(securityContext);
System.out.println(userService.getUserWithAuthorities().isPresent());
}
@Test
public void loginAvailableForAll() throws Exception {
System.out.println(userService.getUserWithAuthorities().isPresent());
}
}您可以使用PowerMock来模拟SecurityContextHolder。 示例mock
SecurityContex
t返回所需角色的列表
import org.junit.Test
导入org.junit.runner.RunWith
导入org.powermock.api.mockito.PowerMockito
导入org.powermock.core.classloader.annotations.PrepareForTest
导入org.powermock.modules.junit4.PowerMockRunner
导入org.springframework.security.authentication.TestingAuthenticationToken
导入org.springframework.security.core.authority.SimpleGrantedAuthority
导入org.springframework.security.core.context.SecurityContext
导入org.springframework.security.core.context.SecurityContextHolder
导入org.springframework.security.core.context.SecurityContextImpl
导入静态org.mockito.mockito.when
@RunWith(PowerMockRunner.class)
@PrepareForTest([SecurityContextHolder.class])
类虚拟{
@试验
void isadmin用户(){
字符串roleList='ROLE\u ADMIN'
mockStatic(SecurityContextHolder)
when(SecurityContextHolder.getContext())。然后返回(getDesiredSecurityContext(roleList))
//assertTrue()
}
//这将创建一个包含所需角色列表的安全上下文
私有SecurityContext getDesiredSecurityContext(字符串角色){
List roleList=roles.split(','))
List authority=roleList.collect{new simplegranteradauthority(it)}
SecurityContext SecurityContext=新的SecurityContextImpl()
securityContext.setAuthentication(新的TestingAuthenticationToken(null,null,authorities))
返回securityContext
}
}
而不是使用PowerMock
自行设置上下文
由于它是静态方法,您可以在@方法之前调用SecurityContextHolder.setContext(securityContext)
示例:
@Before
void initContext(){
SecurityContext securityContext = new SecurityContextImpl();
securityContext.setAuthentication(new TestingAuthenticationToken(null,null,authorities));
SecurityContextHolder.setContext(securityContext);
}
我试过了,没用,在设置了上下文之后,我试着让登录的用户登录,但不存在。您是否花时间阅读了详细说明如何操作的。如果这不起作用,您可能正在编写集成测试,然后您将需要对登录进行编程(调用URL或发送基本身份验证头或…您选择使用的任何身份验证机制)。我尝试了,并附加了上面的代码,但不起作用,继续给我ClassNotFoundException:org.mockito.MockitoAnnotations$Mock。。。请告诉我,我的代码哪一部分有问题这可能是由于mockito和powermock之间的版本不兼容造成的。检查此链接的版本兼容性-好的,它现在可以工作了,但是这部分“Authentication Authentication=this.authenticationManager.authenticate(authenticationToken);”。。。身份验证总是空的,看起来它无法进行身份验证,嗯,如何进行身份验证我实际上模拟了身份验证对象本身-securityContext.setAuthentication(新的TestingAuthenticationToken(空,空,权威))