'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