'How to mock ApplicationContext context = getContext(); of HttpSecurity to prevent nullPointer Exception in below testcase
Upgraded springboot version from 2.5.6 to 2.6.3
After upgrading testcase written for configuration class is throwing nullpointerException.
HttpSecurity.authorizeRequests() throwing NullPointerException in configure() method.
In latest version implementation of ExpressionUrlAuthorizationConfigurer(ApplicationContext context) has been changed and its trying to fetch getBeanNamesForType from ApplicationContext which is resulting in NullpointerException( getContext method called in HttpSecurity-> authorizeRequests returns null in both old and latest version)
TESTCASE
@Mock
AuthenticationManagerBuilder amb;
@Mock
ObjectPostProcessor<Object> opp;
@Mock
Map<Class<? extends Object>, Object> sharedObjects;
@Test
public void configureTrue() throws Exception{
HttpSecurity http=new HttpSecurity(opp, amb, sharedObjects);
SecurityConfig securityConfig=new SecurityConfig();
securityConfig.requireHttps=true;
securityConfig.managementSecurityEnabled=true;
securityConfig.configure(http); //calls conigure method of configuration class(Failing here)
securityConfig.requireHttps=false;
securityConfig.managementSecurityEnabled=false;
assertNotNull(http);
}
App.java(Main method class which has SecurityConfig.class)
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public static class SecurityConfig extends WebSecurityConfigurerAdapter {
@Value("${management.security.enabled}")
protected boolean managementSecurityEnabled;
@Value("${security.require_ssl}")
protected boolean requireHttps;
public boolean isManagementSecurityEnabled() {
return managementSecurityEnabled;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
if (isManagementSecurityEnabled()) {
// authorizeRequests() is the one throwing nullpointerException
http.antMatcher("/management/admin/v1/met/**").authorizeRequests().anyRequest()
.hasRole("ACTUATOR").and().httpBasic();
}
}
}
HttpSecurity.class
public ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry authorizeRequests()
throws Exception {
ApplicationContext context = getContext(); //getting null for context
return getOrApply(new ExpressionUrlAuthorizationConfigurer<>(context)).getRegistry();
}
ExpressionUrlAuthorizationConfigurer
/**
* Creates a new instance
* @see HttpSecurity#authorizeRequests()
*/
public ExpressionUrlAuthorizationConfigurer(ApplicationContext context) {
//Getting failed here(NullPointer Exception) since we are getting context as null
String[] grantedAuthorityDefaultsBeanNames = context.getBeanNamesForType(GrantedAuthorityDefaults.class);
if (grantedAuthorityDefaultsBeanNames.length == 1) {
GrantedAuthorityDefaults grantedAuthorityDefaults = context.getBean(grantedAuthorityDefaultsBeanNames[0],
GrantedAuthorityDefaults.class);
this.rolePrefix = grantedAuthorityDefaults.getRolePrefix();
}
else {
this.rolePrefix = "ROLE_";
}
this.REGISTRY = new ExpressionInterceptUrlRegistry(context);
}
Solution 1:[1]
The following code works:
private HashMap<Class<?>, Object> getSharedObjets(){
HashMap map = new HashMap<Class<?>, Object>();
GenericApplicationContext context= new GenericApplicationContext();
context.refresh();
map.put(ApplicationContext.class, context);
return map;
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Solved Games |
