Search code examples
tddmoqazure-keyvaultazure-sdk-.netazure-secrets

Mock EncryptAsync method and return EncryptResult from Azure.Security.KeyVault.Keys.Cryptography


I am trying to mock the functionality of the EncryptAsync method in Azure.Security.KeyVault.Keys.Cryptography.CryptographyClient.

This is the method I am trying to cover in my unit test.

public KeyVaultClientWrapper(KeyClient keyClient, SecretClient secretClient, CryptographyClient cryptographyClient)
{
    _keyClient = keyClient;
    _cryptographyClient = cryptographyClient;
    _secretClient = secretClient;
}

public async Task<EncryptResult> EncryptAsync(string keyName, string algorithm, byte[] plainText, CancellationToken cancellationToken = default)
{
    return await _cryptographyClient.EncryptAsync(algorithm, plainText, cancellationToken);
}

I'm unable to create new object of EncryptResult that needs to returned from the mock EncryptAsync method because there is no Set for EncryptResult

var _mockKeyVaultClient = new Mock<IKeyVaultClient>();
var _mockCryptoClient = new Mock<CryptographyClient>();
mockCryptoClient
        .Setup(client => client.EncryptAsync(EncryptionAlgorithm.AES, plaintext, default))
        .ReturnsAsync(new EncryptResult { Ciphertext = ciphertext });

How can I change this mock class so that EncryptAsync returns a valid EncryptResult object while running the test method?

Is there any alternate option for testing the same?


Solution

  • For model types that are returned by service operations, a factory class exists to enable creation for unit testing. For your scenario, the CryptographyModelFactory is the class that you're looking for. You would use the EncryptResult method to create your instance.

    For more discussion and details around unit testing and mocking the Azure SDKs, I'd recommend taking a look at Unit testing and mocking with the Azure SDK for .NET which does into more depth on the approach used to ensure testability.