I am in the process of creating tests for AdminClientService, which whould create users into Keycloak database. In the main processing it works as it should, but while creating tests i bumped into this exception:
java.lang.NullPointerException: RESTEASY004645: templateValues entry was null
at com.springboot.services.KeycloakAdminClientServiceTest.createKeycloakUserTest(KeycloakAdminClientServiceTest.java:80)
Here is the test, I am currently running:
@SpringBootTest
public class KeycloakAdminClientServiceTest {
@Value("${keycloak.auth-server-url}")
public String serverUrl;
@Value("${keycloak.realm}")
public String realm;
@Value("${keycloak.resource}")
public String clientId;
@Value("${keycloak.credentials.secret}")
public String clientSecret;
// @Mock
// KeycloakProvider kcProvider = Mockito.mock(KeycloakProvider.class);
// @InjectMocks
//
// @BeforeEach
// void setMockOutput() {
// //when(helloService.get()).thenReturn("Hello Mockito");
// Mockito.when(kcProvider.getInstance()).thenReturn(KeycloakBuilder.builder()
// .realm(realm)
// .serverUrl(serverUrl)
// .clientId(clientId)
// .clientSecret(clientSecret)
// .grantType(OAuth2Constants.CLIENT_CREDENTIALS)
// .build());
// }
KeycloakProvider kcProvider;
KeycloakAdminClientService kcAdminClientService;
@BeforeEach
void createKeycloakProvider() {
kcProvider = new KeycloakProvider();
kcProvider.setServerUrl(serverUrl);
kcProvider.setRealm(realm);
kcProvider.setClientId(clientId);
kcProvider.setClientSecret(clientSecret);
kcAdminClientService = new KeycloakAdminClientService(kcProvider);
}
@Test
public void createKeycloakUserTest(){
Integer generatedInteger = (int) ((Math.random() * (9999999 - 1000000)) + 1000000);
String generatedString = generatedInteger.toString();
CreateUserRequest createUserRequest = new CreateUserRequest();
createUserRequest.setUsername("admin_client_username_" + generatedString);
createUserRequest.setPassword("admin_client_password");
createUserRequest.setEmail("admin_client_email_" + generatedString + "@gmail.com");
createUserRequest.setFirstname("admin_client_firstname_" + generatedString);
createUserRequest.setLastname("admin_client_lastname_" + generatedString);
kcAdminClientService.createKeycloakUser(createUserRequest);
UsersResource usersResource = kcProvider.getInstance()
.realm(kcAdminClientService.realm).users();
List<UserRepresentation> userRepresentation = usersResource
.search("admin_client_email_" + generatedString + "@gmail.com");
assertNotNull(userRepresentation);
assertEquals("admin_client_firstname_" + generatedString,
userRepresentation.get(0).getFirstName());
}
}
Here is the service:
@Service
public class KeycloakAdminClientService {
@Value("${keycloak.realm}")
public String realm;
private final KeycloakProvider kcProvider;
public KeycloakAdminClientService(KeycloakProvider keycloakProvider) {
this.kcProvider = keycloakProvider;
}
public Response createKeycloakUser(CreateUserRequest user) {
UsersResource usersResource = kcProvider.getInstance().realm(realm).users();
CredentialRepresentation credentialRepresentation = createPasswordCredentials(
user.getPassword());
UserRepresentation kcUser = new UserRepresentation();
kcUser.setUsername(user.getEmail());
kcUser.setCredentials(Collections.singletonList(credentialRepresentation));
kcUser.setFirstName(user.getFirstname());
kcUser.setLastName(user.getLastname());
kcUser.setEmail(user.getEmail());
kcUser.setEnabled(true);
kcUser.setEmailVerified(false);
Response response = usersResource.create(kcUser);
return response;
}
private static CredentialRepresentation createPasswordCredentials(String password) {
CredentialRepresentation passwordCredentials = new CredentialRepresentation();
passwordCredentials.setTemporary(false);
passwordCredentials.setType(CredentialRepresentation.PASSWORD);
passwordCredentials.setValue(password);
return passwordCredentials;
}
}
and the KeycloakProvider:
@Configuration
@Getter
@Setter
public class KeycloakProvider {
@Value("${keycloak.auth-server-url}")
public String serverUrl;
@Value("${keycloak.realm}")
public String realm;
@Value("${keycloak.resource}")
public String clientId;
@Value("${keycloak.credentials.secret}")
public String clientSecret;
private static Keycloak keycloak = null;
public KeycloakProvider() {
}
public Keycloak getInstance() {
if (keycloak == null) {
return KeycloakBuilder.builder()
.realm(realm)
.serverUrl(serverUrl)
.clientId(clientId)
.clientSecret(clientSecret)
.grantType(OAuth2Constants.CLIENT_CREDENTIALS)
.build();
}
return keycloak;
}
public KeycloakBuilder newKeycloakBuilderWithPasswordCredentials(
String username,
String password) {
return KeycloakBuilder.builder()
.realm(realm)
.serverUrl(serverUrl)
.clientId(clientId)
.clientSecret(clientSecret)
.username(username)
.password(password);
}
public JsonNode refreshToken(String refreshToken) throws UnirestException {
String url = serverUrl + "/realms/" + realm + "/protocol/openid-connect/token";
return Unirest.post(url)
.header("Content-Type", "application/x-www-form-urlencoded")
.field("client_id", clientId)
.field("client_secret", clientSecret)
.field("refresh_token", refreshToken)
.field("grant_type", "refresh_token")
.asJson().getBody();
}
}
I tried using Mockito for this problem, but realized it won't work, as I wanted it to.