@Theory
  public void createComputeVerifyJwtMac(@FromDataPoints("jwt_mac_templates") String templateName)
      throws Exception {
    KeysetHandle handle = KeysetHandle.generateNew(KeyTemplates.get(templateName));
    JwtMac jwtMac = handle.getPrimitive(JwtMac.class);
    Instant now = Clock.systemUTC().instant();
    RawJwt rawJwt =
        RawJwt.newBuilder()
            .setIssuer("issuer")
            .addAudience("audience")
            .setSubject("subject")
            .addStringClaim("claimName", "claimValue")
            .setExpiration(now.plusSeconds(100))
            .build();
    String token = jwtMac.computeMacAndEncode(rawJwt);

    JwtValidator validator =
        JwtValidator.newBuilder().expectIssuer("issuer").expectAudience("audience").build();
    VerifiedJwt verifiedJwt = jwtMac.verifyMacAndDecode(token, validator);
    assertThat(verifiedJwt.getSubject()).isEqualTo("subject");
    assertThat(verifiedJwt.getStringClaim("claimName")).isEqualTo("claimValue");

    String expiredToken =
        jwtMac.computeMacAndEncode(
            RawJwt.newBuilder()
                .setIssuer("issuer")
                .addAudience("audience")
                .setExpiration(now.minusSeconds(100))
                .build());
    assertThrows(
        GeneralSecurityException.class, () -> jwtMac.verifyMacAndDecode(expiredToken, validator));

    String tokenWithInvalidIssuer =
        jwtMac.computeMacAndEncode(
            RawJwt.newBuilder()
                .setIssuer("invalid")
                .addAudience("audience")
                .setSubject("subject")
                .addStringClaim("claimName", "claimValue")
                .setExpiration(now.minusSeconds(100))
                .build());
    assertThrows(
        GeneralSecurityException.class,
        () -> jwtMac.verifyMacAndDecode(tokenWithInvalidIssuer, validator));

    String tokenWithInvalidAudience =
        jwtMac.computeMacAndEncode(
            RawJwt.newBuilder()
                .setIssuer("issuer")
                .addAudience("invalid")
                .setSubject("subject")
                .addStringClaim("claimName", "claimValue")
                .setExpiration(now.minusSeconds(100))
                .build());
    assertThrows(
        GeneralSecurityException.class,
        () -> jwtMac.verifyMacAndDecode(tokenWithInvalidAudience, validator));

    KeysetHandle otherHandle = KeysetHandle.generateNew(KeyTemplates.get(templateName));
    JwtMac otherJwtMac = otherHandle.getPrimitive(JwtMac.class);
    assertThrows(
        GeneralSecurityException.class, () -> otherJwtMac.verifyMacAndDecode(token, validator));

    assertThrows(
        GeneralSecurityException.class, () -> jwtMac.verifyMacAndDecode("invalid", validator));
    assertThrows(
        GeneralSecurityException.class, () -> jwtMac.verifyMacAndDecode("", validator));
  }
Unit tests for the jwt package. Uses only the public API.
java_src/src/test/java/com/google/crypto/tink/jwt/JwtTest.java