使用Moq 4.18.4配置KeyVaultSecret的ReturnsAsync时遇错误求助
问题描述
使用Moq 4.18.4模拟SecretClient的GetSecretAsync方法时,触发如下编译错误:
ISetup<SecretClient, Task
>' does not contain a definition for 'ReturnsAsync' and the best extension method overload 'SequenceExtensions.ReturnsAsync (ISetupSequentialResult<Task >, Func)' requires a receiver of type 'Moq.Language.ISetupSequentialResult<System.Threading.Tasks.Task<System.Func<Azure.Security.KeyVault.Secrets.KeyVaultSecret>>>'
对应的测试代码:
public async Task GetCertsFromKeyVaultAsync() { // Arrange string certificateName = "MyCertificate"; string base64PrivateKey = "BASE64_PRIVATE_KEY_HERE"; byte[] privateKeyBytes = Convert.FromBase64String(base64PrivateKey); X509Certificate2 expectedCertificate = new X509Certificate2(privateKeyBytes); // Set up the SecretClient to return the expected secret _mockSecretClient.Setup(client => client.GetSecretAsync(certificateName, null, CancellationToken.None)) .ReturnsAsync(() => { return new KeyVaultSecret(certificateName, base64PrivateKey); }); // Act X509Certificate2 actualCertificate = await _keyVaultManager.GetCertificateFromKeyVaultAsync(certificateName); // Assert Assert.AreEqual(expectedCertificate, actualCertificate); ; }
错误原因
GetSecretAsync的实际返回类型是Task<Response<KeyVaultSecret>>,而非直接的Task<KeyVaultSecret>。代码中直接返回KeyVaultSecret实例,导致Moq无法匹配正确的泛型类型,进而找不到对应的ReturnsAsync扩展方法。
修正方案
需要将返回值包装为Response<KeyVaultSecret>类型,Azure SDK提供了Response.FromValue静态方法用于创建模拟响应对象。修正后的Setup代码如下:
_mockSecretClient.Setup(client => client.GetSecretAsync(certificateName, null, CancellationToken.None)) .ReturnsAsync(Response.FromValue(new KeyVaultSecret(certificateName, base64PrivateKey), null));
若需要Lambda写法,可改为:
_mockSecretClient.Setup(client => client.GetSecretAsync(certificateName, null, CancellationToken.None)) .ReturnsAsync(() => Response.FromValue(new KeyVaultSecret(certificateName, base64PrivateKey), null));
另外注意:直接用Assert.AreEqual比较X509Certificate2对象会因引用相等判断失败,建议改用证书的唯一标识做断言:
Assert.AreEqual(expectedCertificate.Thumbprint, actualCertificate.Thumbprint);
内容的提问来源于stack exchange,提问作者Resident Zero9999

