英文:
How do I deal with X509Certificate2 in XUnit tests?
问题
我正在为我的应用程序编写 XUnit 测试,并且需要处理 X509Certificates。我面临的挑战是在 .NET 中无法创建 X509Certificate2 的模拟对象。因此,我正在探索替代方法,以在我的测试环境中有效地处理 X509Certificates。
我考虑过构建一个围绕 X509Certificate2 的包装器,或者使用类似 Certes、CertificateManager 或 BouncyCastle 的库。我的目标是找到一个在简单性、性能和可维护性之间取得平衡的解决方案。
为了让你更好地了解,这是我考虑的包装器的示例:
public interface ICertificate : IDisposable
{
string Subject { get; }
string Thumbprint { get; }
DateTime NotBefore { get; }
DateTime NotAfter { get; }
X509Certificate2 Export();
}
public class Certificate : ICertificate
{
private readonly X509Certificate2 _certificate;
public Certificate(byte[] rawData)
{
_certificate = new X509Certificate2(rawData);
}
public string Subject => _certificate.Subject;
public string Thumbprint => _certificate.Thumbprint;
public DateTime NotBefore => _certificate.NotBefore;
public DateTime NotAfter => _certificate.NotAfter;
public X509Certificate2 Export()
{
return new X509Certificate2(_certificate);
}
public void Dispose()
{
_certificate.Dispose();
}
}
考虑到无法模拟 X509Certificate2 的限制,我倾向于构建这个包装器。然而,我不确定是否这是最佳方法,或者是否利用其中提到的库(Certes、CertificateManager 或 BouncyCastle)会是更明智的选择。
如果你有关于如何高效处理 X509Certificates 的 XUnit 测试的经验或见解,我将非常感激你的建议。此外,如果每种方法都应该注意的优缺点,请分享。非常感谢你提前的帮助!
英文:
I'm working on writing XUnit tests for my application, and I need to deal with X509Certificates. The challenge I'm facing is that it's not possible to create a mock of the X509Certificate2 in .NET. As a result, I'm exploring alternative approaches to effectively handle X509Certificates in my test environment.
I have considered building a wrapper around X509Certificate2 or using libraries like Certes, CertificateManager, or BouncyCastle. My goal is to find a solution that strikes a balance between simplicity, performance, and maintainability.
To give you a better idea, here's an example of the wrapper I'm considering:
public interface ICertificate : IDisposable
{
string Subject { get; }
string Thumbprint { get; }
DateTime NotBefore { get; }
DateTime NotAfter { get; }
X509Certificate2 Export();
}
public class Certificate : ICertificate
{
private readonly X509Certificate2 _certificate;
public Certificate(byte[] rawData)
{
_certificate = new X509Certificate2(rawData);
}
public string Subject => _certificate.Subject;
public string Thumbprint => _certificate.Thumbprint;
public DateTime NotBefore => _certificate.NotBefore;
public DateTime NotAfter => _certificate.NotAfter;
public X509Certificate2 Export()
{
return new X509Certificate2(_certificate);
}
public void Dispose()
{
_certificate.Dispose();
}
}
Given the limitations of mocking X509Certificate2, I am leaning towards building this wrapper. However, I'm unsure if it's the best approach or if utilizing one of the mentioned libraries (Certes, CertificateManager, or BouncyCastle) would be a smarter choice.
If you have experience or insights regarding how to deal with X509Certificates in XUnit tests efficiently, I would greatly appreciate your advice. Additionally, if there are any pros and cons I should be aware of for each approach, please share them. Thank you in advance for your help!
答案1
得分: 1
解决此问题的一种方法如下:
首先,使用 makecert 生成一个证书。
将证书添加到项目(app_data 等)中,然后将构建操作更改为嵌入资源。
最后,按照以下方式加载证书:
byte[] 本地证书;
Assembly 此程序集 = Assembly.GetAssembly(typeof(MyType));
using (Stream 证书流 = 此程序集.GetManifestResourceStream("YourProjectName.localhost.pfx"))
{
本地证书 = new byte[证书流.Length];
证书流.Read(本地证书, 0, (int)证书流.Length);
}
_signingCert = new X509Certificate2(本地证书, "password");
这将为您提供一个本地证书,您可以使用它来编写单元测试。
英文:
One way to resolve the issue can be done by the following:
First, generate a certificate using makecert.
Add the certificate to the project (app_data etc.) and then change Build Action to Embedded Resource.
Finally, load the certificate like below:
byte[] localCertificate;
Assembly thisAssembly = Assembly.GetAssembly(typeof(MyType));
using (Stream certStream = thisAssembly.GetManifestResourceStream("YourProjectName.localhost.pfx"))
{
localCertificate = new byte[certStream.Length];
certStream.Read(embeddedCert, 0, (int)certStream.Length);
}
_signingCert = new X509Certificate2(localCertificate, "password");
This will give you a local certificate and can use it to write unit tests.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论