如何单元测试新的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);
}
}