如何单元测试新的Keycloak身份验证器?

问题描述:

我扩展了Keycloak附带的验证码UsernamePasswordForm。我正在寻找关于如何“单元”测试的例子。如何单元测试新的Keycloak身份验证器?

有没有人有一个例子? 或者可能指向我的某个地方?

我的一位同事最终为我做了这项工作。他的策略很简单,但同时也很烦人。

public abstract class KeycloakTestBase { 
    protected final KeycloakSession session = mock(KeycloakSession.class); 
    protected final HttpRequest request = mock(HttpRequest.class); 
    protected final RealmModel realm = mock(RealmModel.class); 
    protected final UserProvider userProvider = mock(UserProvider.class); 
    protected final UserCredentialManager userCredentialManager = mock(UserCredentialManager.class); 
    protected final EventBuilder eventBuilder = mock(EventBuilder.class); 
    protected final ThemeProvider themeProvider = mock(ThemeProvider.class); 
    protected final Theme theme = mock(Theme.class); 
    protected final KeycloakContext context = mock(KeycloakContext.class); 

    protected KeycloakTestBase() { 
     when(session.userLocalStorage()).thenReturn(userProvider); 
     when(session.userCredentialManager()).thenReturn(userCredentialManager); 
     when(session.getContext()).thenReturn(context); 

     when(context.getRealm()).thenReturn(realm); 

     when(realm.getLoginTheme()).thenReturn("ourtheme"); 

     when(eventBuilder.user(anyString())).thenReturn(eventBuilder); 

     when(userProvider.getUserById(anyString(), eq(realm))).thenReturn(getRandomUser()); 

     when(session.getProvider(ThemeProvider.class, "extending")).thenReturn(themeProvider); 

     try { 
      when(themeProvider.getTheme(anyString(), any(Theme.Type.class))).thenReturn(theme); 
      when(theme.getMessages(any(Locale.class))).thenReturn(new Properties()); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    protected UserModel getRandomUser() { 
     return spy(new InMemoryUserAdapter(session, realm, UUID.randomUUID().toString())); 
    } 
} 

后来用它作为编写新单元测试的基础。这个基类负责将大部分事物连接起来,并返回一些理智的默认值。

扩展基本keycloak类的单元测试类的困难在于,偶尔会碰到一些在keycloak代码中调用的静态方法。如果幸运的话,你可以移除静态代码并将其作为依赖项传入。如果你不幸......那么你是不吉利的。尽管如此,还没有遇到不幸的情况。例如,我们有这个AuthenticationManagerHelper来减轻对静态AuthenticationManager类的呼叫。

public class AuthenticationManagerHelper { 

    public AuthenticationManager.AuthResult authenticateIdentityCookie(KeycloakSession session, RealmModel realm, boolean checkActive) { 
     return org.keycloak.services.managers.AuthenticationManager.authenticateIdentityCookie(session, realm, checkActive); 
    } 
}