shadows/framework/src/main/java/org/robolectric/shadows/ShadowFingerprintManager.java
@Implementation(minSdk = M)
  protected void authenticate(
      CryptoObject crypto,
      CancellationSignal cancel,
      int flags,
      AuthenticationCallback callback,
      Handler handler) {
    if (callback == null) {
      throw new IllegalArgumentException("Must supply an authentication callback");
    }

    if (cancel != null) {
      if (cancel.isCanceled()) {
        Log.w(TAG, "authentication already canceled");
        return;
      } else {
        cancel.setOnCancelListener(() -> {
          this.pendingCallback = null;
          this.pendingCryptoObject = null;
        });
      }
    }

    this.pendingCryptoObject = crypto;
    this.pendingCallback = callback;
  }
@Implementation(minSdk = M)
  protected void authenticate(
      CryptoObject crypto,
      CancellationSignal cancel,
      int flags,
      AuthenticationCallback callback,
      Handler handler) {
    if (callback == null) {
      throw new IllegalArgumentException("Must supply an authentication callback");
    }

    if (cancel != null) {
      if (cancel.isCanceled()) {
        Log.w(TAG, "authentication already canceled");
        return;
      } else {
        cancel.setOnCancelListener(() -> {
          this.pendingCallback = null;
          this.pendingCryptoObject = null;
        });
      }
    }

    this.pendingCryptoObject = crypto;
    this.pendingCallback = callback;
  }
Success or failure can be simulated with a subsequent call to {@link #authenticationSucceeds()}
or {@link #authenticationFails()}.