如何获取 Azure 证书客户端响应和证书指纹

问题描述 投票:0回答:1

我正在尝试对进行证书验证的服务进行单元测试。它将给定指纹与存储在 Azure Key Vault 中的证书上的指纹进行比较。 我的代码工作正常,但现在我正在尝试对其进行单元测试(使用最小起订量)。

为了进行测试,我需要访问/最小起订量检索到的证书的指纹(该证书是类型为

KeyVaultCertificateWithPolicy
的对象。 我的问题是,当我模拟证书的
Properties
对象时,Moq 无法模拟
X509Thumbprint
,因为设置器是内部的。

我使用以下代码收到以下错误:

System.NotSupportedException:不支持的表达式:x => x.X509Thumbprint 不可重写的成员(此处:CertificateProperties.get_X509Thumbprint)不得在设置/验证表达式中使用。

这是我的单元测试代码的摘录:

var azCertificateProps = new Mock<CertificateProperties>();
azCertificateProps.SetupGet(x => x.X509Thumbprint).Returns(testThumbprint); // Fails here
var azCertificate = new Mock<KeyVaultCertificateWithPolicy>(azCertificateProps.Object);

作为参考,这是我正在尝试进行单元测试的实际代码(简化)

public KeyVaultCertificateWithPolicy ExpectedCertificate { get; set; }

public async Task<bool> ValidateCertificate(X509Certificate2 clientCertificate, CancellationToken cancellationToken)
{
    return clientCertificate.Thumbprint == BitConverter.ToString(ExpectedCertificate.Properties.X509Thumbprint).Replace("-", "");
}

我尝试实例化

KeyVaultCertificateWithPolicy
对象本身,但我仍然找不到以任何方式传递我的指纹的方法。

c# unit-testing moq azure-keyvault
1个回答
0
投票

异常实际上不是由

internal
setter 引起的。这是因为 Moq 的工作方式(以及大多数其他模拟框架)是通过
override
-ing 方法或属性。在 dotnet 中,您只能覆盖
virtual
事物。

这就是为什么 Moq 通常与接口配合得很好,因为一切都是

virtual
。但对于具体的类,您将开始遇到这些限制。

这是一个例子:

class Test { public int Prop {get; set;} }
class TestVirt { public virtual int Prop {get; set;} }

new Mock<Test>().SetupGet(x => x.Prop).Returns(1); // FAILS!
new Mock<TestVirt>().SetupGet(x => x.Prop).Returns(1); // works

// Same problems with non-virtual methods.

对于类,通常我们只是创建它的实例而不是模拟。但我们已经知道它对你不起作用,因为

internal
setter。

这就是我们拿出

System.Reflection
的神秘大部头的地方,使用类型系统为我们提供了对象内部的后门。如果我们愿意,我们甚至可以设置
private
变量,只要我们知道它的名字。

var testThumb = new byte[] { 1, 2, 3 };
var certProps = new CertificateProperties("");

typeof(CertificateProperties)
  .GetProperty("X509Thumbprint")? // Get property by name,
  .SetValue(certProps, testThumb); // and set its value.

Debug.Assert(certProps.X509Thumbprint.SequenceEqual(testThumb));

反射的一个缺点是我们使用其名称的

string
来获取类成员。如果类提供者决定更改其签名并删除属性,您只会在运行时而不是编译时发现。

© www.soinside.com 2019 - 2024. All rights reserved.