RealWhorlwind extends Whorlwind { @Override public Completable write(@NonNull final String name, @Nullable final ByteString value) { return Completable.fromAction(new Action() { @Override public void run() throws Exception { checkCanStoreSecurely(); synchronized (dataLock) { if (value == null) { storage.remove(name); return; } prepareKeyStore(); Cipher cipher = createCipher(); cipher.init(Cipher.ENCRYPT_MODE, getPublicKey()); storage.put(name, ByteString.of(cipher.doFinal(value.toByteArray()))); } } }); } RealWhorlwind(Context context, FingerprintManager fingerprintManager, Storage storage,
      String keyAlias, KeyStore keyStore, KeyPairGenerator keyGenerator, KeyFactory keyFactory); @Override boolean canStoreSecurely(); @Override Completable write(@NonNull final String name, @Nullable final ByteString value); @Override Observable<ReadResult> read(@NonNull String name);  }
@Test public void writeThrowsOnSubscribeWhenCannotStoreSecurely() { shadowContext.denyPermissions(USE_FINGERPRINT); Throwable expected = whorlwind.write("test", ByteString.encodeUtf8("test")).blockingGet(); assertThat(expected).hasMessage( "Can't store securely. Check canStoreSecurely() before attempting to read/write."); verifyZeroInteractions(storage); }