@Test
public void testDefaultOAuthJwtAccessTokenValidator() {

    // on null or empty
    BiConsumer<Supplier<DefaultOAuthJwtAccessTokenValidator>, String> assertThrowable = (func, expectedErrMsg) -> {
        DefaultOAuthJwtAccessTokenValidator validator = null;
        try {
            validator = func.get();
        } catch (IllegalArgumentException e) {
            assertEquals(e.getMessage(), expectedErrMsg);
            return;
        } finally {
            assertNull(validator);
        }
        fail("assertThrowable: does not throw");
    };
    assertThrowable.accept(() -> {
        return new DefaultOAuthJwtAccessTokenValidator(null, this.requiredAudiences, this.requiredScopes, this.authorizedClientIds);
    }, "trusted issuers must be configured");
    assertThrowable.accept(() -> {
        return new DefaultOAuthJwtAccessTokenValidator("", this.requiredAudiences, this.requiredScopes, this.authorizedClientIds);
    }, "trusted issuers must be configured");
    assertThrowable.accept(() -> {
        return new DefaultOAuthJwtAccessTokenValidator(this.trustedIssuer, null, this.requiredScopes, this.authorizedClientIds);
    }, "required audiences must be configured");
    assertThrowable.accept(() -> {
        return new DefaultOAuthJwtAccessTokenValidator(this.trustedIssuer, new HashSet<>(), this.requiredScopes, this.authorizedClientIds);
    }, "required audiences must be configured");
    assertThrowable.accept(() -> {
        return new DefaultOAuthJwtAccessTokenValidator(this.trustedIssuer, this.requiredAudiences, null, this.authorizedClientIds);
    }, "required scopes must be configured");
    assertThrowable.accept(() -> {
        return new DefaultOAuthJwtAccessTokenValidator(this.trustedIssuer, this.requiredAudiences, new HashSet<>(), this.authorizedClientIds);
    }, "required scopes must be configured");
    assertThrowable.accept(() -> {
        return new DefaultOAuthJwtAccessTokenValidator(this.trustedIssuer, this.requiredAudiences, this.requiredScopes, null);
    }, "client ID mapping must be configured");
    // actual value
    BiFunction<Field, DefaultOAuthJwtAccessTokenValidator, Object> getFieldValue = (f, object) -> {
        try {
            f.setAccessible(true);
            return f.get(object);
        } catch (IllegalArgumentException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    };
    DefaultOAuthJwtAccessTokenValidator validator = new DefaultOAuthJwtAccessTokenValidator(this.trustedIssuer, this.requiredAudiences, this.requiredScopes, this.authorizedClientIds);
    assertNotNull(validator);
    for (Field f : validator.getClass().getDeclaredFields()) {
        switch (f.getName()) {
            case "trustedIssuer":
                assertSame(getFieldValue.apply(f, validator), this.trustedIssuer);
                break;
            case "requiredAudiences":
                assertSame(getFieldValue.apply(f, validator), this.requiredAudiences);
                break;
            case "requiredScopes":
                assertSame(getFieldValue.apply(f, validator), this.requiredScopes);
                break;
            case "authorizedClientIds":
                assertSame(getFieldValue.apply(f, validator), this.authorizedClientIds);
                break;
        }
    }
}