nishantvas
nishantvas

Reputation: 304

How to programmatically Autowire a bean based on Qualifier Annotation

In Junit5, when using Extensions, we can run BeforeAll and AfterAll methods, and I'm trying to change behaviour of the test using Annotations. However, I'm using these annotations as @Qualifiers as well for bean initialisation, and want to be able to initialise a bean using the Annotation identified on the test

I wish to programmatically Initialise the Bean on run time using my Qualifier Annotations I know SpringExtension for Junit5 can get

SpringExtension.getApplicationContext(context).getAutowireCapableBeanFactory()

Using which I can call the bean initialisation factory, but I don't know how to initialise the beans using Annotations which are Qualifiers I have multiple Beans of same type, identified by Qualifiers

The problem I'm stuck with is

Currently, I'm statically initialising the Type of user credentials using AutoWired and then basis the annotation I'm using the pre-initialized UserCredential using switch case.

The idea is to have a test class @ExtendsWith(ResetPortal.class) and then it indicates, which type of user it can use to Reset (Login before test) with. I'm using Qualifier Annotations to indicate that, which I can then extract from ExtensionContext from the Junit5 beforeAll methods

Further, I have a UserCredential class being and multiple @Bean definitions for that class for each type of user.

Code

Bean definition, using custom qualifier annotation User1Qualifier

@Bean
  @User1Qualifier
  public static UserCredentials clientBankLogin(
      @Value(LOGIN_USERNAME_1) String username,
      @Value(LOGIN_PASSWORD_1) String password) {
    return new UserCredentials(username, password);
  }

With my Custom qualifier being as below (there are multiple)

@Qualifier
@CustomValueAnnotation("User1")
@Retention(RUNTIME)
@Target({FIELD, PARAMETER, TYPE, METHOD})
public @interface User1Qualifier {}

Now, in the tests, I'm trying to use the same Annotation, which the ResetPortal picks up

@SpringBootTest
@ExtendWith({ResetPortal.class, SpringExtension.class})
final class LoginTest extends SpringTestBase {

      @Test
      @User1Qualifier
      void clientLogin() {}
}

The ResetPortal class, since Junit5 initialises the class and calls it's managed instance, needs Autowired elements to be defined separately

@Service
public class ResetPortal implements BeforeEachCallback, AfterEachCallback {

     static UserCredentials user1;
     static UserCredentials user2;

     Autowired
     public void initializeLoginToPortal(@User1Qualifier UserCredentials u1, 
                                         @User2Qualifier UserCredentials u2) {
                 user1 = u1;
                 user2 = u2;
    }

    @Override
      public void beforeEach(ExtensionContext context) {

      // This is the custom Value annotation marked on each UserQualifier
      // This is using AnnotationUtils#findAnnotation(java.lang.Class<?>, java.lang.Class<A>)
      CustomValueAnnotation loginAs = getLoginAsAnnotation(context);

      switch (loginAs){
       case "User1" : loginWith(ResetPortal.user1); break;
       case "User2" : loginWith(ResetPortal.user2); break;
      }
    }
}

Upvotes: 1

Views: 531

Answers (0)

Related Questions