0

In many of my integration tests, I have to create Entities with a custom security context. Then within tests I use another security context to check for example the access rights. So I created a new annotation:

@Retention(RetentionPolicy.RUNTIME)
@WithSecurityContext(factory = CustomSecurityContextFactory.class)
public @interface WithCustomUser {

  String username();

  String[] roles() default {"USER"};
}

This is the CustomSecurityContextFactory class:

@Component
@RequiredArgsConstructor
public class CustomSecurityContextFactory implements WithSecurityContextFactory<WithCustomUser> {

  // dependencies

  @Override
  public SecurityContext createSecurityContext(WithCustomUser withCustomUser) {
    SecurityContext context = SecurityContextHolder.createEmptyContext();
    OAuth2AccessToken token = buildToken();
    Employee employee = employeeService.findByUsername(withCustomUser.username());

    Map<String, Object> attributes = new HashMap<>();
    attributes.put("username", withCustomUser.username());
    List<String> roles = List.of(withCustomUser.roles());
    List<GrantedAuthority> authorities = buildAuthorities(roles, attributes);

    employee.setAuthorities(authorities);
    employee.setUsername(withCustomUser.username());
    employee.setPassword(token.getTokenValue());

    UsernamePasswordAuthenticationToken authentication =
        new UsernamePasswordAuthenticationToken(employee, token.getTokenValue(), authorities);

    context.setAuthentication(authentication);

    return context;
  }
}

I can now easily use the annotation above test methods like this:

@Test
@WithCustomUser(username = "myUsername")
void simpleTest() {
  Order order = orderService.createOrder();  
  assertThat(order.getEmployee().getUsername()).isEqualTo("myUsername");
}

This works great. but I would like to create the order in beforeAll method and use it in the tests. something like this:

@BeforeAll
@WithCustomUser(username = "myUsername")
void beforeAllNonStatic() {
    Order order = orderService.createOrder();
}

But this obviously doesn't work. when it tries to create the order, employee is null. I currently use static mocking in beforeAll method and that works. but is there a way to make the annotation work? Am I using the annotation at the wrong place?

MehdiB
  • 870
  • 12
  • 34

0 Answers0